资讯专栏INFORMATION COLUMN

leetcode402. Remove K Digits

paraller / 2217人阅读

摘要:当我们用尽了所有删除时,就保留后面所有的数字,不再进行任何比较。因为我们已经尽可能获得了最小的最高位,因此无论后面的数字如何取值,其最高位上的数字一定是可以获得的最小的这个数字。

题目要求
Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.

Note:
The length of num is less than 10002 and will be ≥ k.
The given num does not contain any leading zero.
Example 1:

Input: num = "1432219", k = 3
Output: "1219"
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
Example 2:

Input: num = "10200", k = 1
Output: "200"
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
Example 3:

Input: num = "10", k = 2
Output: "0"
Explanation: Remove all the digits from the number and it is left with nothing which is 0.

假设现在有一个用字符串表示的非负的整数,问从中删除掉k个数字后能够得到的最小结果是多少?

思路和代码

直观的来说,删除数字得到最小的数字意味着我们应当尽可能的将越小的数字保留在高位,因此当我们从左往右遍历时,一旦遇到比前一个数字更小的数字,就应当删除前一个数字而保留这个数字。当我们用尽了所有删除时,就保留后面所有的数字,不再进行任何比较。因为我们已经尽可能获得了最小的最高位,因此无论后面的数字如何取值,其最高位上的数字一定是可以获得的最小的这个数字。举个例子:

10200 k=1
第一步: 0和1比较,此时0比1小,且还有一次可用的删除,因此删除1,保留0
第二步:因为无可用的删除次数,因此剩下的值全部保留

123450123 k=5
第一步:2>1 保留
第二步:3>2 保留
第三步: 4>3 保留
第四步: 5>4 保留
第五步:0<5 删除5 保留0 k=4
第六步: 0<4 删除4 保留0 k=3
第七步:0<3 删除3 保留0 k=2
第八步:0<2 删除2 保留0 k=1
第九步:0<1 删除1 保留0 k=0
第十步: 此时所有的删除次数用完,因此剩余的值全部保留

可以看到,当我们遇到较小值时,我们会尽可能的将其往左边移动,因为只要它比左边的值小且剩余删除次数,则删除左边的值一定会得到一个更小的值。

代码如下:

    public String removeKdigits(String num, int k) {
        if(num == null || num.length() == 0 || k==num.length()) return "0";
        Stack stack = new Stack<>();
        for(int i = 0 ; i < num.length() ; i++) {
            char c = num.charAt(i);
            while(k> 0 && !stack.isEmpty() && stack.peek() > c) {
                stack.pop();
                k--;
            }
            stack.push(c);
        }
        
        while(k > 0) {
            stack.pop();
            k--;
        }
        
        StringBuilder result = new StringBuilder();
        while(!stack.isEmpty()) {
            result.append(stack.pop());
        }
        while(result.length() > 1 && result.charAt(result.length()-1) == "0") {
            result.deleteCharAt(result.length()-1);
        }
        return result.reverse().toString();
    }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73610.html

相关文章

  • 402. Remove K Digits

    摘要:题目链接根据题目的描述,移掉个数字然后得到最小值,肯定是。后面的和需要移掉也是同理。用个来保存之前递增的数字。注意这个例子,去掉之后,最高位是,也得去掉。 402. Remove K Digits 题目链接:https://leetcode.com/problems... 根据题目的描述,移掉k个数字然后得到最小值,肯定是greedy。那么greedy的feature是什么呢?看例子,...

    sf190404 评论0 收藏0
  • 316. Remove Duplicate Letters and 402. Remove K Di

    摘要:每个字母只留一个,而且保证字典序最小。从前往后扫描,还要往前看一个检出是否删除的,要用解。需要一个数据结构记录是否使用这个字母,可以用。结构也可以用数组加顶点指针模拟。 316 Remove Duplicate Given a string which contains only lowercase letters, remove duplicate letters so that e...

    novo 评论0 收藏0
  • 初识“回溯算法”讲解及LeetCode对应例题解析

    摘要:回溯算法的基本思想是从一条路往前走,能进则进,不能进则退回来,换一条路再试。回溯算法的一般解题思路定义一个解空间,它包含问题的解。 初识回溯算法讲解及LeetCo...

    BingqiChen 评论0 收藏0
  • leetcode-357-Count Numbers with Unique Digits

    摘要:此模型的特殊性相邻的三个值可以得到一个爆破值,相邻的两个值相当于没有值,赋予类比二分法求极值。通过二分确定具体的位置。此处二分法到极值是三个连续的数,从相邻三个数的固定值,逐次放宽范围,确定越来越宽的爆破值。 此题的总结: 求解 最大爆破值, 是一个 倒序 二分法问题,最终的原子结构是连续的三个数。连续的三个数,可以 往上递推 间隔一个数的三个数,间隔n个数的三个数特点在于:每一...

    lansheng228 评论0 收藏0
  • LeetCode[321] Create Maximum Number

    摘要:算法复杂度思路贪心算法,先能组成的数的组合,然后针对每一个组合,考虑每一个数组能够组成的最大的位或者位数。对不同组合生成的最大数进行比较,得到所能得到的最大的值。代码的方法去找这个数。 LeetCode[321] Create Maximum Number Given two arrays of length m and n with digits 0-9 representing ...

    UsherChen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<