1. 解析
题目大意,从字符串表示的数里面移除n个数字,使其代表的数最小
2. 分析
对于数值的大小,我们知道,高位上的数字越大,所代表的的数越大,即若要使一个数越小,只需保证高位上的数字越小即可,所以我们只需从高位往低位检索,若当前高位上的数字大于次高位上的数字,将其删除;若小于,继续往下检索,直到删除第k个即可。需要注意的一点是:字符串的首字符有可能会出现'0',别忘了删除
class Solution {
public:
string removeKdigits(string num, int k) {
if (num.empty()) return "";
if (num.length() == k) return "0";
for (int i = 1; i < num.length(); ){
if (num[i] < num[i-1]){ //当高位比低一位的上的数字大的时候,去除
num = num.substr(0, i-1) + num.substr(i);
if (--i == 0) i = 1; //防止高位连续出现较大的数,例如num = "9967", k = 2
if (--k == 0) break;
}
else{
i++;
}
}
while (! num.empty() && num[0] == '0') num = num.substr(1); //去除前面的'0'
while (!num.empty() && k-- > 0) //经过上面的处理,未必就删除掉k个数,所以要在这里进行处理
num.pop_back();
return num.empty() ? "0" : num;
}
};
3. 简便的解法
参考博主@Grandyang的解法,虽然思路是一样的,但我更欣赏他这种处理方式。详见代码,不解释了,简单易懂
class Solution {
public:
string removeKdigits(string num, int k) {
string res = "";
int keep = num.size() - k;
for (char ch : num){
while (k && res.length() && res.back() > ch){ //将高位上大于次高位的数删除
res.pop_back();
k--;
}
res.push_back(ch);
}
res.resize(keep); //只截取前keep个字符,例如res = "1234", keep = 2, 则经过处理后res = "12"
while (!res.empty() && res[0] == '0'){ //去除字符串开头'0'的字符
res.erase(res.begin()); //这个写法也很值得我们学习,也可以写成 res = res.substr(1);
}
return res.empty() ? "0" : res;
}
};