给定一个以字符串表示的非负整数 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。
思路
通过分析例子
如1432219 k=1时:
432219
132219
142219
143219
143229
143221
在k=1的情况下,选择最小的数‘132219’进行移除数字,当k=2时:
32219
12219
13219
13221
在k=2的情况下,选择最小的数‘12219’进行移除数字,当k=3时:
2219
1219
1221
通过以上的分析,发现选出的最小的数”1432219,132219,12219,1219“
都是先在高位选择所能选的最小的数字,因为高位的大小优先决定整个数的大小
我们通过栈来完成操作
- 1、大于栈顶的先暂存栈顶
- 2、小于栈顶的则push当前栈顶,将小的数push
class Solution {
public:
string removeKdigits(string num, int k) {
std::vector<int> s;//用vector当作栈,因为他也可以遍历
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){
//pop就是删除的条件,栈顶大于新数字删,栈不为空可以删。k大于0可以删
s.pop_back();
k--;
}
if(number!=0 || s.size()!=0){//push是保留数字的情况,1,数字不为0 或2,栈不为空(就是无前导0)
s.push_back(number);
}
}
while(s.size()!=0 && k > 0){//栈不空 k大于0 仍然可以删
s.pop_back();
k--;
}
for(int i = 0; i < s.size(); i++){//数字转字符
result.append(1, '0'+s[i]);
}
if(result == "") result = "0";//全都删了输出的是0.实例3
return result;
}
};