Leetcode402、移掉K位数字

1、问题描述

给定一个以字符串表示的非负整数 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。

2、思考与分析

3、贪心规律

4、使用栈来优化求解

5、需要注意的问题

  • 当所有数字都扫描完成后,k仍然>0,应该做怎样的处理? 例如: num = 12345, k = 3 时。
  • 当数字中有0出现时,应该有怎样的特殊处理? 例如: num = 100200, k = 1 时。
  • 如何将最后结果存储为字符串并返回?

6、代码实现

#include 
#include 
#include 

using namespace std;

class Solution
{
public:
    string removeKdigits(string num, int k)
    {
        vector S;  // 使用vector当作栈,方便遍历操作
        string result = "";  // 存储最终结果

        for (int i = 0; i < num.length(); i++)  // num.size() is ok!
        {
            int number = num[i] - '0';  // 数字字符转整型数字 '3' -> 3

            // 这个循环的作用是:在k还有机会的情况下(k > 0),
            // 要将S中,从后到前,比number大的全部删除掉
            while (S.size() != 0 && S[S.size() - 1] > number && k > 0)
            {
                // S.size() != 0 说明还没有将num的字符压入到S中,或者被弹空了
                // S[S.size() - 1] > num 说明新来的数字小,比当前S尾部的元素值更有利于使整体变小
                // k > 0 说明还有机会删除数字
                S.pop_back();  // 当上述三个条件都满足时,弹出S尾部元素
                k --;  // 用掉一次弹出数字的机会
            }

            // 如果上述循环不满足条件
            // 如果number != 0 ,那就可以将其压入
            // 如果number == 0,但只要S.size() != 0就可以将其压入
            // 这两点保证是因为,数字不能以一个0或者一串连续的0开头
            // if (number != 0 || S.size() != 0)
            if (number != 0)
            {
                // 只所以能到这一步,是因为比该number大的,在k > 0范围内,全部被干掉了,
                // 当前S.size()会终止一下
                // 不过当前number是0的话,虽然全部把前面的干掉了,但是0不能当作首元素
                S.push_back(number);
            }
        }

        // 这种情况是,k的次数没有用完,就像12345678这种一样
        // 注意:这里的S.size() != 0 是有必要的,因为最后可能只剩了尾部的0
        // 而这些0是没有压入的S中,所以这种情况就是,S为空,但k > 0还满足,num也遍历完了
        while (S.size() != 0 && k > 0)
        {
            // 只能从尾部用剩下的机会删除
            S.pop_back();
            k --;
        }

        // 到目前位置,S中剩下的元素,就是经过元素删除后满足条件的
        for (int i = 0; i < S.size(); i ++)
        {
            result.append(1, '0' + S[i]);
        }

        if (result == "")
        {
            result = "0";
        }

        return result;
    }
};

int main()
{
    string num = "10200";

    int k = 1;
    Solution S;
    string res = S.removeKdigits(num, k);

    cout << res << endl;
    return 0;
}

你可能感兴趣的:(Leetcode402、移掉K位数字)