Coding Patterns · Monotonic Increasing Stack
Leetcode 402: Remove K Digits
Use a monotonic increasing stack to remove larger earlier digits when a smaller digit arrives, producing the smallest possible number after k removals.
View Leetcode 402: Remove K DigitsMonotonic Increasing Stack Animation
Remove K Digits uses this idea: when a smaller digit arrives, remove larger digits before it.
The Intuition
Remove K Digits asks for the smallest possible number after deleting exactly k digits. The most important idea is this: digits on the left matter more than digits on the right.
Example: in 43, removing 4 is better than removing 3, because 3 in the left position makes the whole number smaller.
That is why this problem uses a monotonic increasing stack. The stack tries to keep digits increasing from bottom to top. When the current digit is smaller than the stack top, the increasing rule is broken, so we pop.
Why Knowing The Pattern Is Not Enough
It is normal to still feel stuck even after hearing “use an increasing stack.” The missing step is understanding what the stack represents.
The stack is not just storing digits. It is storing the best number prefix we can build so far. Every time a new digit arrives, we ask: can this digit make the prefix smaller by removing something before it?
If yes, pop the larger digit. If no, push the current digit.
Walkthrough: num = 1432219, k = 3
Start with an empty stack. We want the smallest possible number after three removals.
- Read 1. Stack is empty, so push it.
- Read 4. Since 4 >= 1, push it.
- Read 3. Since 3 < 4, pop 4. This makes the number smaller.
- Read 2. Since 2 < 3, pop 3.
- Read another 2. Since 2 >= 2, keep it and push.
- Read 1. Since 1 < 2, pop one 2. Now k is zero, so we cannot pop anymore.
- Push the remaining digits. The answer is 1219.
The Rule
While the stack is not empty, removals are still available, and the current digit is smaller than the stack top, pop.
while (
stack.length > 0 &&
k > 0 &&
stack[stack.length - 1] > digit
) {
stack.pop();
k--;
}After that loop stops, push the current digit.
Java Solution
class Solution {
public String removeKdigits(String num, int k) {
Deque<Character> stack = new ArrayDeque<>();
for (char digit : num.toCharArray()) {
while (!stack.isEmpty() && k > 0 && stack.peek() > digit) {
stack.pop();
k--;
}
stack.push(digit);
}
while (!stack.isEmpty() && k > 0) {
stack.pop();
k--;
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
sb.append(stack.removeLast());
}
while (sb.length() > 0 && sb.charAt(0) == '0') {
sb.deleteCharAt(0);
}
return sb.length() == 0 ? "0" : sb.toString();
}
}Why The End Cleanup Exists
Sometimes the digits never decrease enough to trigger pops. For example, with 12345, the stack stays increasing the whole time.
If k is still greater than zero after the loop, remove digits from the end. Those are the least valuable positions to keep because they are farthest to the right.
Complexity
Time complexity is O(n) because each digit is pushed once and popped at most once. Space complexity is O(n) for the stack.