LeetCode 402. Remove K Digits
给你一个以字符串表示的非负整数 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 。
提示:
1 <= k <= num.length <= 105 num 仅由若干位数字(0 - 9)组成 除了 0 本身之外,num 不含任何前导零
算法1
(贪心) O(n)
思路:尽可能让最高位小,最高位相同的情况下尽可能让次高位小,所以应该维护一个非递减栈。
构建一个非递减栈stk:从左往右遍历数字num,依次进栈;每个数字x进栈前检查是否比栈顶,是的话弹掉栈顶;全部数字一共有k次机会弹栈顶(相当于,最多在这一步删掉k个数字) 如果k次(删数字的)机会没有用完,则弹出栈顶直到stk中剩余stk.size()−k个数字,将stk倒出来再reverse,统计前导0的个数,并以此返回对应的值 举例,在Example 1中,输入为 num = “1432219”, k = 3,输出为”1219”。
第一步,构造stk
的步骤是, (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 对象中指定位置的子字符串。
C++ 代码
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);
}
};