Remove K Digits solution and explanation
9 more videos on this problem
L14. Remove K Digits | Stack and Queue Playlisttake U forward · 15:29 · 158K views
Remove K digits | Build lowest number | Leetcode #402Techdose · 15:30 · 93K views
Remove K Digits - Leetcode 402 - PythonNeetCode · 14:36 · 78K views
Remove K Digits | Intuition | Dry Run | Leetcode 402 | codestorywithMIKcodestorywithMIK · 35:07 · 24K views
LeetCode Remove K Digits Solution Explained - JavaNick White · 11:06 · 22K views
402. Remove K Digits | Monotonic Stack | Greedy | Brute Force - Optimal SolutionAryan Mittal · 24:06 · 6K views
Remove K Digits | Remove K Digits LeetCode Solution Java | LeetCode 402Programming Tutorials · 11:24 · 3K views
Remove K Digits | remove k digits | remove k digits leetcode | leetcode 402Akshay Goyal · 8:53 · 1K views
Remove K Digits | Leetcode - 402Algorithms Made Easy · 3:48 · 1K views
Daily Leetcode #1472: Apr 11, 2024 - 402. Remove K DigitsProgramming Live with Larry · 15:26 · 709 views
The problem
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 <= 105numconsists of only digits.numdoes not have any leading zeros except for the zero itself.
Approach overview
Problem Overview: You receive a numeric string num and an integer k. Remove exactly k digits so the resulting number is as small as possible while preserving the relative order of the remaining digits. Leading zeros must be handled carefully, and if all digits are removed the result should be "0".
Approach 1: Brute Force Digit Removal (Exponential time, O(2^n) time, O(n) space)
The naive strategy explores all ways to remove k digits and keeps the smallest resulting number. You recursively choose whether to remove or keep each digit until exactly k removals are made. After constructing each candidate string, normalize leading zeros and compare it against the current minimum. This approach demonstrates the core goal of minimizing the number but quickly becomes impractical because the number of combinations grows exponentially. It only works for very small inputs and mainly serves as a conceptual baseline.
Approach 2: Greedy Monotonic Stack (Optimal) (O(n) time, O(n) space)
The optimal strategy uses a greedy rule: remove digits that create a larger prefix. If a digit is bigger than the next one, deleting it makes the number smaller. A monotonic stack captures this idea efficiently. Iterate through the digits of num. While the stack is not empty, the current digit is smaller than the top of the stack, and you still have removals left (k > 0), pop the stack. This removes a larger digit that would otherwise increase the final number.
Push each processed digit onto the stack. After the scan, if k removals remain, remove digits from the end since the suffix is the largest remaining portion. Finally, build the result string from the stack and trim leading zeros. If the string becomes empty, return "0". The stack effectively maintains digits in increasing order, making this a classic combination of greedy, stack, and string processing techniques.
Recommended for interviews: Interviewers expect the monotonic stack solution. It shows you recognize the greedy property: removing a larger digit before a smaller one always improves the number. The brute force idea proves you understand the objective, but the stack-based O(n) solution demonstrates strong algorithmic thinking and familiarity with monotonic data structures.
Approach 1: Monotonic Stack Approach
This approach uses a stack to build the smallest possible number. We iterate over each digit in the string, and for each digit, we compare it with the top of the stack (if the stack is not empty). If the current digit is smaller than the top of the stack and we still have digits to remove, we pop from the stack. Finally, after the loop, if there are remaining digits to remove, we simply remove them from the end of the constructed stack. This ensures the smallest possible arrangement of the remaining digits.
def removeKdigits(num: str, k: int) -> str:
stack = []
for digit in num:
while k > 0 and stack and stack[-1] > digit:
stack.pop()
k -= 1
stack.append(digit)
# If k still > 0, remove the remaining digits from the end
final_stack = stack[:-k] if k else stack
# Convert to string and remove leading zeros
return ''.join(final_stack).lstrip('0') or '0'import java.util.Stack;
public class Solution {
public String removeKdigits(String num, int k) {
Stack<Character> stack = new Stack<>();
for (char digit : num.toCharArray()) {
while (k > 0 && !stack.isEmpty() && stack.peek() > digit) {
stack.pop();
k--;
}
stack.push(digit);
}
StringBuilder result = new StringBuilder();
while (!stack.isEmpty()) {
result.append(stack.pop());
}
result.reverse();
while (result.length() > 1 && result.charAt(0) == '0') {
result.deleteCharAt(0);
}
return result.length() == 0 ? "0" : result.substring(0, result.length() - k);
}
}#include <iostream>
#include <string>
#include <stack>
using namespace std;
string removeKdigits(string num, int k) {
stack<char> st;
for (char digit : num) {
while (k > 0 && !st.empty() && st.top() > digit) {
st.pop();
--k;
}
st.push(digit);
}
string result = "";
while (!st.empty()) {
result += st.top();
st.pop();
}
reverse(result.begin(), result.end());
result = result.substr(0, result.size() - k);
auto it = result.find_first_not_of('0');
result = it != string::npos ? result.substr(it) : "0";
return result;
}function removeKdigits(num, k) {
const stack = [];
for (let digit of num) {
while (k > 0 && stack.length && stack[stack.length - 1] > digit) {
stack.pop();
k--;
}
stack.push(digit);
}
stack.splice(stack.length - k, k);
while (stack.length && stack[0] === '0') {
stack.shift();
}
return stack.length ? stack.join('') : '0';
}#include <stdio.h>
#include <string.h>
char *removeKdigits(char *num, int k) {
int len = strlen(num);
// Resultant stack array
char *stack = (char *)malloc(len + 1);
int top = -1, toRemove = k;
for (int i = 0; i < len; i++) {
char c = num[i];
while (top >= 0 && stack[top] > c && toRemove > 0) {
top--;
toRemove--;
}
stack[++top] = c;
}
// The final size should be len - k
top = top - toRemove;
stack[top + 1] = '\0';
// Strip leading zeros
int offset = 0;
while (stack[offset] == '0') offset++;
// Check for the 'emptiness' of the string
if (offset > top) return "0";
return stack + offset;
}using System;
using System.Text;
public class Solution {
public string RemoveKdigits(string num, int k) {
var stack = new Stack<char>();
foreach (var digit in num) {
while (k > 0 && stack.Count > 0 && stack.Peek() > digit) {
stack.Pop();
k--;
}
stack.Push(digit);
}
var result = new StringBuilder();
foreach (var digit in stack) {
result.Append(digit);
}
result.Length -= k;
var strResult = new string(result.ToString().Reverse().ToArray());
return strResult.TrimStart('0') == "" ? "0" : strResult.TrimStart('0');
}
}This Python implementation utilizes a stack to keep track of the most desirable sequence of digits. As the function iterates over each digit, it determines whether the stack should pop any elements based on whether doing so would create a smaller number. After the loop, any remaining digits are removed by slicing off the end of the stack. Leading zeros are removed from the final result, and if this leads to an empty string, we return '0'.
Time Complexity: O(n), where n is the number of digits in num, because each digit is processed at most twice (once pushed and once popped).
Space Complexity: O(n), because of the space required for the stack to hold the digits.
Approach 2: Greedy Algorithm
function removeKdigits(num: string, k: number): string {
const stk: string[] = [];
for (const c of num) {
while (k && stk.length > 0 && stk[stk.length - 1] > c) {
stk.pop();
k--;
}
stk.push(c);
}
while (k--) {
stk.pop();
}
return stk.join('').replace(/^0*/g, '') || '0';
}func removeKdigits(num string, k int) string {
stk, remain := make([]byte, 0), len(num)-k
for i := 0; i < len(num); i++ {
n := len(stk)
for k > 0 && n > 0 && stk[n-1] > num[i] {
stk = stk[:n-1]
n, k = n-1, k-1
}
stk = append(stk, num[i])
}
for i := 0; i < len(stk) && i < remain; i++ {
if stk[i] != '0' {
return string(stk[i:remain])
}
}
return "0"
}Complexity comparison
| Approach | Complexity |
|---|---|
| Monotonic Stack Approach | Time Complexity: O(n), where n is the number of digits in |
| Greedy Algorithm | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Digit Removal | O(2^n) | O(n) | Conceptual understanding or very small inputs |
| Greedy Monotonic Stack | O(n) | O(n) | Optimal approach for large inputs and interview settings |
Frequently asked questions
Is Remove K Digits easy or hard?
Remove K Digits is rated Medium on LeetCode. The implementation is straightforward once you recognize the greedy rule and apply a monotonic stack, but identifying that insight can be challenging for beginners.
Remove K Digits Python/Java solution
Most implementations follow the same monotonic stack pattern. Use a list as a stack in Python or a Deque/StringBuilder in Java, pop while the previous digit is larger than the current one and k is positive, then build the result while removing leading zeros.
How to solve Remove K Digits in O(n)?
Traverse the number from left to right while maintaining a stack of digits. While the stack top is larger than the current digit and k is still positive, pop the stack to remove the larger digit. Push the current digit, and after traversal remove remaining digits from the end if k > 0, then strip leading zeros.
What is the best approach for Remove K Digits?
The optimal solution uses a greedy monotonic stack. Iterate through the digits and remove previous digits while the current digit is smaller and removals are still allowed. This guarantees the smallest possible prefix and runs in O(n) time with O(n) space.
Is Remove K Digits asked at Google/Amazon/Meta?
Remove K Digits is a common greedy and monotonic stack interview problem and has appeared in coding interviews at companies like Amazon, Google, and other large tech firms. It tests your ability to identify greedy choices and implement stack-based optimization.
What data structure is used in Remove K Digits?
The primary data structure is a stack used in a monotonic increasing manner. The stack helps efficiently remove previously chosen digits when a smaller digit appears, ensuring the smallest possible number is constructed.
What is the time complexity of Remove K Digits?
The optimal monotonic stack solution runs in O(n) time where n is the number of digits in the string. Each digit is pushed and popped from the stack at most once. Space complexity is O(n) for the stack storing the resulting digits.
