leetcode 链接:402. 移掉 K 位数字

题目

给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。

示例:

  1. 输入:num = "1432219", k = 3
  2. 输出:"1219"
  3. 解释:移除掉三个数字 4, 3, 2 形成一个新的最小的数字 1219
输入:num = "10200", k = 1
输出:"200"
解释:移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
输入:num = "10", k = 2
输出:"0"
解释:从原数字移除所有的数字,剩余为空就是 0 。

解答 & 代码

单调栈 (栈顶到栈底的元素从大到小)

class Solution {
public:
    string removeKdigits(string num, int k) {
        stack<int> s;    // 单调栈,栈顶到栈底的元素从大到小
        for(int i = 0; i < num.size(); ++i)
        {
            // 如果栈顶的元素大于当前元素,则弹出栈顶(即移除栈顶这个数字)
            while(!s.empty() && s.top() > num[i] - '0' && k > 0)
            {
                s.pop();
                --k;
            }
            s.push(num[i] - '0');
        }
        // 如果移掉的数字数量小于 k,继续移除
        while(!s.empty() && k > 0)
        {
            s.pop();
            --k;
        }

        string result;
        while(!s.empty())
        {
            result += '0' + s.top();
            s.pop();
        }
        int idx = result.size() - 1;
        while(idx >= 0 && result[idx] == '0')    // 删除前导0
        {
            result.pop_back();
            --idx;
        }
        if(result.size() == 0)    // 如果删除签到0后变为空,说明为0,返回 0
            return "0";
        reverse(result.begin(), result.end());    // 逆序
        return result;
    }
};

执行结果:

执行结果:通过

执行用时:8 ms, 在所有 C++ 提交中击败了 34.48% 的用户
内存消耗:7.2 MB, 在所有 C++ 提交中击败了 21.67% 的用户