402. 移掉 K 位数字(单调栈)
难度中等
给你一个以字符串表示的非负整数 num
和一个整数 k
,移除这个数中的 k
位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
示例 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 。
class Solution: def removeKdigits(self, num: str, k: int) -> str: n = len(num) remain = n - k stack = [] for i in range(n): cur = num[i] # stack 内递增,所以小于栈顶的弹出 while k > 0 and stack and cur < stack[-1]: top = stack.pop() k -=1 stack.append(cur) res = "".join(stack[:remain]).lstrip('0') if res == "": res = '0' return res
class Solution: def removeKdigits(self, num: str, k: int) -> str: stk = [] nk = len(num)-k for n in num: while k > 0 and stk and n < stk[-1]: stk.pop() k-=1 stk.append(n) # nk 排除这种345 全递增的 res = "".join(stk[:nk]).lstrip("0") if res =="": res = "0" return res
class Solution { public: //要让剩下数字最小,就要保证靠前的数字尽可能小(贪心)。比如425,要删去4,也就是说看到从左到右有递减的序列, //就要删掉左边的大数字;如果没有这样的序列,比如是245,那就删除最后一个数字 string removeKdigits(string num, int k) { stack<char> stk; string res; for(int i = 0; i < num.size();i++) { while(k > 0 && !stk.empty() && num[i] < stk.top()) { stk.pop(); k--; } stk.push(num[i]); } // for cases like "456" where every num[i] > num.top() while(!stk.empty()&& k>0) { stk.pop(); k--; } while(!stk.empty()) { res+=stk.top(); stk.pop(); } reverse(res.begin(),res.end()); // 删除前置0 ,比如02000 int fk = 0; while(res[fk]=='0' && fk < res.size()) { fk++; } std::string res_clean = res.substr(fk,res.size()-fk); return ( res_clean== "")? "0":res_clean; } };