Given string num representing a non-negative integer num
, and an integer k
, return the smallest possible integer after removing k
digits from num
.
Example 1:
Input: num = "1432219", k = 3 Output: "1219" Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
Example 2:
Input: num = "10200", k = 1 Output: "200" Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
Example 3:
Input: num = "10", k = 2 Output: "0" Explanation: Remove all the digits from the number and it is left with nothing which is 0.
Constraints:
1 <= k <= num.length <= 105
num
consists of only digits.num
does not have any leading zeros except for the zero itself.
题目链接:https://leetcode.com/problems/remove-k-digits/
题目大意:删除k个字符使剩下的数字最小
题目分析:首先想到如果某个0的前面非0数字个数小于k,则这些数字必应被删除,因为可以减少数字位数,把这部分处理掉之后对剩余部分通过单调栈维护一个递增序列,如果存在递减的部分,将较大数字删除必能使答案更小,以下代码
4ms,时间击败96.84%
class Solution {
public String removeKdigits(String num, int k) {
char[] nums = num.toCharArray();
int n = nums.length;
if (n == k) {
return "0";
}
int[] zPos = new int[n];
int[] zCnt = new int[n];
int cnt = 0, m = 0;
for (int i = 0; i < n; i++) {
if (nums[i] == '0') {
while (i + 1 < n && nums[i + 1] == '0') {
i++;
}
zPos[m] = i;
zCnt[m++] = cnt;
cnt = 0;
} else {
cnt++;
}
}
int pos = 0;
for (int i = 0; i < m && zCnt[i] <= k; i++) {
pos = zPos[i] + 1;
k -= zCnt[i];
}
if (pos >= n) {
return "0";
}
StringBuffer sb = new StringBuffer("");
char[] stk = new char[n + 1];
int top = 0;
stk[++top] = nums[pos++];
while (k > 0 && pos < n) {
if (nums[pos] < stk[top]) {
while (k > 0 && top > 0 && nums[pos] < stk[top]) {
k--;
top--;
}
}
stk[++top] = nums[pos++];
}
if (pos == n) {
top -= k;
}
for (int i = 1; i <= top; i++) {
sb.append(stk[i]);
}
for (int i = pos; i < n; i++) {
sb.append(nums[i]);
}
if (sb.length() == 0) {
return "0";
}
return sb.toString();
}
}