移除k个数字最大为多少(贪心+栈)
题目描述
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
题解
思路:尽可能让最高位小,最高位相同的情况下尽可能让次高位小,所以应该维护一个非递减栈。
构建一个非递减栈stk:从左往右遍历数字num,依次进栈;每个数字x进栈前检查
是否比栈顶,是的话弹掉栈顶;全部数字一共有k次机会弹栈顶(相当于,最多在这一步删掉k个数字)
如果k次(删数字的)机会没有用完,则弹出栈顶直到stkstk中剩余stk.size()−k个数字
将stk倒出来再reverse,统计前导0的个数,并以此返回对应的值
举例,在Example 1中,输入为 num = “1432219”, k = 3,输出为”1219”。
第一步,构造stkstk的步骤是, (stk=1,k=3) –> (stk=14,k=3) –> (stk=13,k=2) –> (stk=12,k=1) –> (stk=122,k=1) –> (stk=12,k=0) –> (stk=121,k=0) –> (stk=1219,k=0)
第二步,k已经等于0了
第三步,(stk=1219) –> (res=”9121”) –> (res=”1219”) –> i=0,res.substr(i)=”1219“
相关语法小细节:最后return调用的res.substr(i)
string.substr(start , [length]) :返回一个从指定位置开始的指定长度的子字符串
string.substring(start, end) :返回位于 String 对象中指定位置的子字符串。
Code
class Solution { public: string removeKdigits(string num, int k) { stack<char> stk; for (auto x : num) { while (stk.size() && stk.top() > x && k) { stk.pop(); k--; } stk.push(x); } while (k -- ) stk.pop(); string res; while (stk.size()) { res += stk.top(); stk.pop(); } reverse(res.begin(), res.end()); int i = 0; while (i < res.size() && res[i] == '0') i++; if (i == res.size()) return "0"; return res.substr(i); } };