移除k个数字最大为多少(贪心+栈)

题目描述

传送门

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

题解

思路:尽可能让最高位小,最高位相同的情况下尽可能让次高位小,所以应该维护一个非递减栈。

构建一个非递减栈stk:从左往右遍历数字num,依次进栈;每个数字x进栈前检查
是否比栈顶,是的话弹掉栈顶;全部数字一共有k次机会弹栈顶(相当于,最多在这一步删掉k个数字)

如果k次(删数字的)机会没有用完,则弹出栈顶直到stkstk中剩余stk.size()−k个数字

将stk倒出来再reverse,统计前导0的个数,并以此返回对应的值

举例,在Example 1中,输入为 num = “1432219”, k = 3,输出为”1219”。

第一步,构造stkstk的步骤是, (stk=1,k=3) –> (stk=14,k=3) –> (stk=13,k=2) –> (stk=12,k=1) –> (stk=122,k=1) –> (stk=12,k=0) –> (stk=121,k=0) –> (stk=1219,k=0)

第二步,k已经等于0了

第三步,(stk=1219) –> (res=”9121”) –> (res=”1219”) –> i=0,res.substr(i)=”1219“

相关语法小细节:最后return调用的res.substr(i)

string.substr(start , [length]) :返回一个从指定位置开始的指定长度的子字符串

string.substring(start, end) :返回位于 String 对象中指定位置的子字符串。

Code

class Solution {
public:
    string removeKdigits(string num, int k) {
        stack<char> stk;
        for (auto x : num)
        {
            while (stk.size() && stk.top() > x && k)
            {
                stk.pop();
                k--;
            }
            stk.push(x);
        }

        while (k -- ) stk.pop();

        string res;
        while (stk.size())
        {
            res += stk.top();
            stk.pop();
        }
        reverse(res.begin(), res.end());
        int i = 0;
        while (i < res.size() && res[i] == '0') i++;
        if (i == res.size()) return "0";
        return res.substr(i);
    }
};

 

posted @ 2021-08-30 20:34  lipu123  阅读(129)  评论(0)    收藏  举报