
402
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
注意:
- num 的长度小于 10002 且 ≥ k。
- num 不会包含任何前导零。
示例 1 :
1 2 3
|
输入: num = "1432219", k = 3 输出: "1219" 解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。
|
单调栈
1 2 3 4 5
|
stack<int> s; while (!s.empty() && s.top() > /input/) { s.pop(); } s.push(/input/);
|
Example
$$a_1,a_2,a_3,a_4,a_5,a_6,a_7 cdots a_n$$
对每个 i,求出一个区间 [li, ri]。满足 ai 是区间 [li, ri] 中的最小值,并且区间尽可能大。保证 ai 互不相同。
1 2 3 4
|
a = 1 8 4 5 6 3 2 7 id = 1 2 3 4 5 6 7 8
i = 3, ai = 4。[li, ri] = [2, 5]。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
int n; int a[MAXN], l[MAXN], r[MAXN];
void () { stack<int> s; a[0] = a[n + 1] = INT_MIN for (int i = 0; i <= n + 1; ++i) { while (!s.empty() && a[s.top()] > a[i]) { r[s.top()] = i - 1; s.pop(); }; if (!s.empty){ l[i] = s.top() + 1; } s.push(i); } }
|
- 要让数位单调不降。例如 …43…。如果我不删掉43,那么前缀为 …4;否则前缀为 …3,一定优于前者。
- 用单调栈维护,每次压入栈顶的时候,弹出栈顶严格大于当前元素的栈中元素。
- 注意只能删掉 k 个元素。所以要在弹栈的时候加上限制。并且,如果数位已经单调不降,而 k 还有剩余,那么显然删掉末尾(栈顶) k 个元素。
- 还要去掉前导 0。
- 如果答案串为空串,将其设置为 0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
class Solution { public: string removeKdigits(string num, int k) { stack<char> s; for (int i = 0; i < num.length(); ++i) { while (k && !s.empty() && s.top() > num[i]) { s.pop(); k--; } s.push(num[i]); } string ans; while (!s.empty()) { if (k) { --k; } else { ans += s.top(); } s.pop(); } reverse(ans.begin(), ans.end()); int i; for (i = 0; ans[i] == ‘0’; i++); ans = ans.substr(i, ans.length() - i); if (ans == “”) { ans = “0”; } return ans; } };
|
近期评论