402. 移掉K位数字

402. 移掉K位数字

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

注意:

num 的长度小于 10002 且 ≥ k。
num 不会包含任何前导零。

示例 1 : 

输入: num = "1432219", k = 3
输出: "1219"
解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。

示例 2 : 

输入: num = "10200", k = 1
输出: "200"
解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。

示例 3 : 

输入: num = "10", k = 2
输出: "0"
解释: 从原数字移除所有的数字,剩余为空就是0。


基本思路:先举一个特例,对于字符串s,仅仅删除一个元素,a)若s=1234,显然删除最后一个元素;b)若s=4321,显然删除第一个元素;c)若s=1243,经过对比发现,删除4时最小。

  • 对于长度相同的数,从左向右,第一个不同的数小的值比较小。
  • 若一个序列为严格递增时,删除前面的数,会导致值变大。
  • 在删除数时,当删除一个逆序数时,如c)中4>3,删除4时,值变小,其他操作值变大,

数据结构的选择,相当于保存了一个单增栈,故可以使用栈结构,亦可以使用双端队列,甚至vector也可以。

注:如果要求剩余的值最大,删除顺序数即可,即stk[top]>num[i]改为stk[top]<num[i]

    string removeKdigits(string num, int k) {
        int  len=num.size();
        int top=-1;
        string ans="";
        if(len<=k)
            return "0";
        
        vector<char> stk(num.size());
        for(int i=0;i<num.size();i++){
            while(top!=-1&&stk[top]>num[i]&&k){  //逆序删除
                top--;
                k--;
            }
            stk[++top]=num[i];
        }
        while(k--){ //若没有删够,此时stk内的元素是非递减序列,只需从后往前删除k个元素即可。  
            top--; 
        }

        int pos=0;
        while(stk[pos]=='0'&&pos<top)  //删除前导零,若结果为零,保留最后一位零
            pos++;
        while(pos<=top)
            ans.push_back(stk[pos++]);
        return ans;
        
    }

python版本 

    def removeKdigits(self, num: str, k: int) -> str:
        stack=[]
        top=-1
        for digit in num:
            while k and stack and stack[-1]>digit:
                stack.pop()
                k-=1
            stack.append(digit)

        remain=len(num)-k
        return ''.join(stack[:remain]).lstrip('0') or '0'

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值