移除K个数字
题目
已知一个使用字符串表示的非负整数num,将num中的K个数字移除,求移除K个数字后,可以获得的最小的可能的新数字。
例如:
输入:num = “1432219”,k = 3
在去除3个数字后得到的很多可能里,如1432、4322、2219、1219、1229…;其中以去掉数字4、3、2得到的1219最小!
思路
因为越高位的数字决定的大小比低位更有效,所以如果要最小的数字,需要尽可能让新数字优先最高位最小,次高位最小,次次高位最小…最终直到移除够K个数字
建立一个数字字符栈,从字符串开头开始,按顺序压入栈中,当k仍然>0时,且新遍历的数字字符如果比栈顶元素大则不放入栈中,即移除该数字字符,若不大于栈顶元素,则放入到栈中保留,直至移除够K个数字后,将还未放入的数字字符全部放入栈中,则达到了使越高位(越接近栈底)的数字越小,最终数字最小。
当然还考虑到数字中有0出现时,应该有怎样的特殊处理?
例如:num = 100200,k=1时。
应该去除1,因为它比0大,然后因为栈为空,高位的数字为0无意义,所以不放入栈中,最终结果为200,其为最小。
最后就是将栈中储存的数字字符储存为字符串并返回:
按找倒着的顺序,将栈顶元素放在字符串末尾(S.size()-1),形成字符串返回。
过程如图所示:
代码如下:
#include <stdio.h>
#include <string>
#include <stack>
class Solution {
public:
std::string removeKdigits(std::string num, int k) {
std::stack<int> S;
std::string result = "";
for (int i = 0; i < num.length(); i++){
int number = num[i] - '0';
while(S.size() != 0 && S[S.size()-1] > number && k > 0){
S.pop();
k--;
}
if (number != 0 || S.size() != 0){
S.push(number);
}
}
while(S.size() != 0 && k > 0){
S.pop();
k--;
}
for (int i = S.size() - 1; i >= 0; i--){
result[i] = S.top();
S.pop();
}
if (result == ""){
result = "0";
}
return result;
}
};
致谢
本章知识点和思路由小象学院相关视频提供,由本人学习并梳理得出,希望自己加深记忆的同时,也能给大家提供更多有关于一些算法的知识点。
你的点赞、评论、收藏就是对我最大的支持与鼓励,谢谢!