题目意思:
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
贪心思路:
对于数字的从高到低位每一位都遍历一次,使得最高位在满足条件的情况下尽可能的取到最小,越高位小则整体小。如 "10200"这个字符串,对于第一位想要取最小,"10200"中第二位0满足条件,如果最高位取这个0,只需删掉一个数1,而删除一个数刚好满足我们的条件,所以,第一位可以取0;
优化:记录删除的个数,如果删除的个数已经达到题目要求的个数,直接break掉,把后面的字符直接加到结果集后面。
class Solution {
public:
string removeKdigits(string num, int k) {
string res = "";
//越高位越应该小
int rest = k;
//上次取的下标
int lastIndex = -1;
//标记字符是否取过
int flagString[num.length() + 5];
//初始化
memset(flagString, 0, sizeof(flagString));
for(int j = 0; j < num.length() - k; j++){
if(rest == 0) break;
int min = 20;
//当前暂时取的下标
int tmpIndex = 0;
for(int i = lastIndex+1; i < num.length(); i++){
//判断会不会删多了
if((i-lastIndex-1) <= rest && (num[i] - '0' < min) && flagString[i] == 0){
//暂时取该值
min = num[i] - '0';
tmpIndex = i;
}
}
//更新
rest -= (tmpIndex - lastIndex - 1);
lastIndex = tmpIndex;
flagString[tmpIndex] = 1;
if((num[tmpIndex] - '0') == 0){
//前导零
if(res.length() > 0){
res += num[tmpIndex];
}
}else res += num[tmpIndex];
}
for(int i = lastIndex+1+rest; i < num.length(); i++){
//如果提前删够了直接把后面的拼上去
if((num[i] - '0') == 0){
//前导零
if(res.length() > 0){
res += num[i];
}
}else res += num[i];
}
//“0”的情况
if(res.length() == 0) return "0";
else return res;
}
};