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.The problem asks to find the smallest possible integer after removing k
digits from the input string num
. A greedy approach is effective here. The core idea is to iteratively remove the largest digit that is to the left of a smaller digit. This is because removing a larger digit earlier will result in a smaller overall number.
Initialization: Use a stack (stk
) to store digits. We also track the number of digits remaining (remain
) after removing k
digits. remain = len(num) - k
.
Iteration: Iterate through each digit (c
) in the input string num
.
Greedy Removal: While k
is greater than 0 and the stack is not empty and the top of the stack (stk[-1]
) is greater than the current digit (c
):
k
(we've removed one digit).Push to Stack: Push the current digit (c
) onto the stack.
Handle Remaining k: After the loop, if k
is still greater than 0 (meaning we need to remove more digits), pop the last k
digits from the stack. This handles cases where the digits are monotonically increasing (e.g., "12345").
Remove Leading Zeros: Convert the stack to a string, remove any leading zeros, and handle the case where the result is an empty string (representing 0).
num
. The algorithm iterates through the string once. Stack operations (push and pop) take constant time.Python:
class Solution:
def removeKdigits(self, num: str, k: int) -> str:
stk = []
remain = len(num) - k
for c in num:
while k and stk and stk[-1] > c: # Greedy step: remove larger digit to the left of smaller
stk.pop()
k -= 1
stk.append(c) # Add current digit
return ''.join(stk[:remain]).lstrip('0') or '0' # Remove leading zeros, handle empty string
Java:
class Solution {
public String removeKdigits(String num, int k) {
StringBuilder stk = new StringBuilder(); // Use StringBuilder for efficient string manipulation
for (char c : num.toCharArray()) {
while (k > 0 && stk.length() > 0 && stk.charAt(stk.length() - 1) > c) {
stk.deleteCharAt(stk.length() - 1); // remove larger digit
--k;
}
stk.append(c);
}
//Handle remaining k
while (k-- > 0) stk.deleteCharAt(stk.length()-1);
int i = 0;
while (i < stk.length() && stk.charAt(i) == '0') i++; // remove leading zeros
return i == stk.length() ? "0" : stk.substring(i);
}
}
The other languages (C++, Go, TypeScript) follow a similar pattern, adapting the core algorithm to the specifics of each language's syntax and data structures. The key ideas of the greedy algorithm remain consistent across all implementations.