[LeetCode] 402. Remove K Digits
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.
移掉 K 位数字。
给你一个以字符串表示的非负整数 num
和一个整数 k
,移除这个数中的 k
位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
思路是贪心,会用到单调栈。这里我们需要思考一个问题,什么样的数字才是最小的?首先高位的数字需要尽可能的低,可以尝试用 stack,从左往右把每一位 push 到 stack,当 stack 不为空且栈顶元素比要 push 进去的元素要大的时候,pop 出栈顶元素,直到丢弃了 K 个数字为止。但是这个题也有一些 corner case,比如第二个例子,10200,放弃一个数字,按照之前的思路,会丢弃掉 1,但是剩下的部分是 0200,需要处理掉开头的 0;再看第三个例子,10,需要去掉 2 个数字,会使得 res 成为 0。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public String removeKdigits(String num, int k) { 3 // corner case 4 if (k == num.length()) { 5 return "0"; 6 } 7 8 // normal case 9 Stack<Character> stack = new Stack<>(); 10 for (int i = 0; i < num.length(); i++) { 11 while (k > 0 && !stack.isEmpty() && stack.peek() > num.charAt(i)) { 12 stack.pop(); 13 k--; 14 } 15 stack.push(num.charAt(i)); 16 } 17 18 while (k > 0) { 19 stack.pop(); 20 k--; 21 } 22 23 StringBuilder sb = new StringBuilder(); 24 while (!stack.isEmpty()) { 25 sb.append(stack.pop()); 26 } 27 sb.reverse(); 28 29 int index = 0; 30 // skip the leading zeros 31 while (index < sb.length() && sb.charAt(index) == '0') { 32 index++; 33 } 34 return index == sb.length() ? "0" : sb.substring(index); 35 } 36 }
JavaScript实现
1 /** 2 * @param {string} num 3 * @param {number} k 4 * @return {string} 5 */ 6 var removeKdigits = function(num, k) { 7 // corner case 8 if (num === null || num.length === 0) { 9 return '0'; 10 } 11 12 // normal case 13 let stack = []; 14 for (let i = 0; i < num.length; i++) { 15 while (k > 0 && stack.length && num.charAt(i) < stack[stack.length - 1]) { 16 stack.pop(); 17 k--; 18 } 19 stack.push(num.charAt(i)); 20 } 21 22 while (k > 0) { 23 stack.pop(); 24 k--; 25 } 26 27 let sb = stack.join(''); 28 let res = 0; 29 while (res < sb.length && sb.charAt(res) === '0') { 30 res++; 31 } 32 return res === sb.length ? '0' : sb.substring(res); 33 };