Remove K Digits



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位,使得新的数字最小。

这道题目可以采用贪心算法,就是从字符串的头部向尾部扫,只要发现前面的数字比后面的小就移除前面的这个数字,如果移除的位已经等于k或者已经到达字符串的尾部就停止,如果扫完了字符串后移除的位还不足k,就直接把最后面的位去掉。

因为在字符串前面的数字代表的权重肯定比后面的数字大,所以只要这里的数字能够减小1,肯定比这位不改变而去改变后面的数字所得到的数字小。而如果按照这种方法把整个字符串扫完,那么字符串中的数字肯定是按递增的顺序排列的,所以如果还要继续删除数字,就只需要删除后面的数字就可以了。所以这个算法是正确的。

但是在实现的时候对下标要非常注意,比如在移除了第i个数字以后,还要拿原来的i-1个数字和原来的i+1(现在为i)个数字比较,我在实现的时候就是因为没有考虑到这个问题导致答案错误,还浪费了非常多的时间。由于题目要求把最前面的0去掉,所以最后要特判一下,把最前面的0去掉,如果最后字符串为空,则返回字符串“0”。

这个算法只用了一重循环,但是循环内部使用了erase函数,我并不清楚它的复杂度,如果它的复杂度为O(1)的话,那么这个算法的复杂度为O(n)。

以下为源代码:

class Solution {
public:
    string removeKdigits(string num, int k) {
        for(int i=0;i<num.size()-1;i++)
        {
            if(k==0) break;
            if(num[i]>num[i+1]) 
            {
                num.erase(i,1);
                k--;
                i-=2;
                if(i<-1) i=-1;
            }
        }
        if(k>0)
        {
            num.erase(num.size()-k,k);
        }
        int i=0;
        while(true)
        {
            if(num[i]!='0') break;
            i++;
        }
        num.erase(0,i);
        if(num.size()==0) return "0";
        return num;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值