LeetCode 移掉K位数字(402题)

LeetCode 移掉K位数字(402题)

@author:Jingdai
@date:2020.10.24

题目描述(402题)

给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

  • 注意

     num 的长度 ≥ k
     num 不会包含任何前导零
    
  • 示例输入

    num = "1432219", k = 3
    
  • 示例输出

    "1219"
    
  • 解释

    移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。
    

思路

题目要求是移除 k 位数字,所以最后剩下的数字的长度是一定的,即为 num.length() - k ,所以我们可以直接考虑对于长度固定的子数的最小值是多少。

而对于一个固定长度的数来说,数的大小取决于第一个不一样的数,如 123axyz123bznz 的大小取决于 ab 的大小,当 a > b 时, 123axyz > 123bznz ,反之亦然。

所以我们应该从左往右遍历,对于每个数字考虑舍弃还是保留。那怎么确定一个数是保留还是舍弃呢?将这个数和之前那个数进行比较,如果这个数比之前那个数小,就将之前的那个数舍弃,如果之前的数仍然大于当前数,则继续舍弃。看下面的栗子就懂了。

对于示例中的 "1432219" ,首先第一个数 1 没有和它比较的数,所以直接过。然后第二个数如图,4 > 1,所以选择保留 1 ,这里其实就是比较 14

在这里插入图片描述

如图,对于第三个数 33 < 4,所以选择去掉 4 ,这里其实是比较 1413 哪个更小,显然 13 更小,然后就把 4 去掉了。然后继续比较 133 > 1 所以保留 1 。然后继续下一个数 2 …直到删除k个数字。

在这里插入图片描述

但是这样会漏掉一种情况,就是可能遍历完也没有删除完 k 个数字,比如对于数 "123456" 这样的数,删除 3 个数,显然按照刚才的方法遍历完也是 6 位,对于这种情况,可以直接截取剩下数的前 num.length() - k 位即可。

同时,会发现这个题目很容易用 stack 来实现,每次比较栈顶元素和当前元素,pop 出比当前数字大的元素,然后 push 当前数字。

代码如下。

代码

public static String removeKdigits(String num, int k) {
     
     
   
       if (num.length() == 0) {
     
     
           throw new RuntimeException("Wrong Num!");
       } 

       LinkedList<Character> stack = new LinkedList<>();
       int tempK = k;
       for (int i = 0; i < num.length(); i++) {
     
     
           while (tempK > 0 && stack.size() != 0 && num.charAt(i) < stack.peek()) {
     
     
               tempK--;
               stack.pop();
           }
           stack.push(num.charAt(i));
       }

       StringBuilder sb = new StringBuilder();
       boolean isHeadingZero = true;
       for (int i = 0; i < num.length() - k; i++) {
     
     
           Character tempNumber = stack.removeLast();
           if (isHeadingZero && tempNumber == '0') {
     
     
               continue;
           }
           isHeadingZero = false;
           sb.append(tempNumber);
       }
   
       return sb.length() == 0 ? "0" : sb.toString();
   }

猜你喜欢

转载自blog.csdn.net/qq_41512783/article/details/109265825