🧠
Brute Force (Generate All Combinations)
💡 This approach exists to understand the problem deeply by trying all possible ways to remove k digits. It is impractical for large inputs but helps grasp the problem's combinatorial nature.
Intuition
Try every combination of removing k digits and pick the smallest resulting number. This brute force method guarantees correctness but is very inefficient.
Algorithm
- Generate all combinations of indices to remove of size k.
- For each combination, build the number by skipping those indices.
- Compare all generated numbers and keep track of the smallest.
- Return the smallest number after removing leading zeros or '0' if empty.
💡 The challenge is generating all combinations and comparing results, which is conceptually simple but computationally expensive.
from itertools import combinations
def removeKdigits(num: str, k: int) -> str:
n = len(num)
if k == n:
return "0"
min_num = None
indices = range(n)
for remove_indices in combinations(indices, k):
remove_set = set(remove_indices)
candidate = ''.join(num[i] for i in range(n) if i not in remove_set).lstrip('0')
if candidate == '':
candidate = '0'
if min_num is None or candidate < min_num:
min_num = candidate
return min_num
# Driver code
if __name__ == '__main__':
print(removeKdigits("1432219", 3)) # Expected: "1219"
Line Notes
from itertools import combinationsImport combinations to generate all removal sets
if k == n:If we remove all digits, result is '0'
for remove_indices in combinations(indices, k):Try every combination of k indices to remove
candidate = ''.join(num[i] for i in range(n) if i not in remove_set).lstrip('0')Build candidate number skipping removed digits and strip leading zeros
import java.util.*;
public class RemoveKDigitsBrute {
public static String removeKdigits(String num, int k) {
int n = num.length();
if (k == n) return "0";
String minNum = null;
List<Integer> indices = new ArrayList<>();
for (int i = 0; i < n; i++) indices.add(i);
List<List<Integer>> combos = combinations(indices, k);
for (List<Integer> removeIndices : combos) {
Set<Integer> removeSet = new HashSet<>(removeIndices);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
if (!removeSet.contains(i)) sb.append(num.charAt(i));
}
String candidate = sb.toString().replaceFirst("^0+", "");
if (candidate.isEmpty()) candidate = "0";
if (minNum == null || candidate.compareTo(minNum) < 0) minNum = candidate;
}
return minNum;
}
private static List<List<Integer>> combinations(List<Integer> arr, int k) {
List<List<Integer>> result = new ArrayList<>();
backtrack(arr, k, 0, new ArrayList<>(), result);
return result;
}
private static void backtrack(List<Integer> arr, int k, int start, List<Integer> temp, List<List<Integer>> result) {
if (temp.size() == k) {
result.add(new ArrayList<>(temp));
return;
}
for (int i = start; i < arr.size(); i++) {
temp.add(arr.get(i));
backtrack(arr, k, i + 1, temp, result);
temp.remove(temp.size() - 1);
}
}
// Driver
public static void main(String[] args) {
System.out.println(removeKdigits("1432219", 3)); // Expected: "1219"
}
}
Line Notes
if (k == n) return "0";If all digits removed, return '0'
for (List<Integer> removeIndices : combos)Try every combination of indices to remove
String candidate = sb.toString().replaceFirst("^0+", "");Remove leading zeros from candidate
if (minNum == null || candidate.compareTo(minNum) < 0)Keep track of lex smallest candidate
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
void backtrack(const vector<int>& arr, int k, int start, vector<int>& temp, vector<vector<int>>& result) {
if ((int)temp.size() == k) {
result.push_back(temp);
return;
}
for (int i = start; i < (int)arr.size(); i++) {
temp.push_back(arr[i]);
backtrack(arr, k, i + 1, temp, result);
temp.pop_back();
}
}
vector<vector<int>> combinations(const vector<int>& arr, int k) {
vector<vector<int>> result;
vector<int> temp;
backtrack(arr, k, 0, temp, result);
return result;
}
string removeKdigits(string num, int k) {
int n = (int)num.size();
if (k == n) return "0";
vector<int> indices(n);
for (int i = 0; i < n; i++) indices[i] = i;
vector<vector<int>> combos = combinations(indices, k);
string minNum = "";
for (auto& removeIndices : combos) {
set<int> removeSet(removeIndices.begin(), removeIndices.end());
string candidate = "";
for (int i = 0; i < n; i++) {
if (removeSet.find(i) == removeSet.end()) candidate += num[i];
}
candidate.erase(0, candidate.find_first_not_of('0'));
if (candidate.empty()) candidate = "0";
if (minNum.empty() || candidate < minNum) minNum = candidate;
}
return minNum;
}
int main() {
cout << removeKdigits("1432219", 3) << endl; // Expected: 1219
return 0;
}
Line Notes
if (k == n) return "0";Return '0' if all digits removed
vector<vector<int>> combos = combinations(indices, k);Generate all combinations of indices to remove
candidate.erase(0, candidate.find_first_not_of('0'));Remove leading zeros from candidate
if (minNum.empty() || candidate < minNum) minNum = candidate;Track lex smallest candidate
function removeKdigits(num, k) {
const n = num.length;
if (k === n) return "0";
const indices = [...Array(n).keys()];
function combinations(arr, k) {
const result = [];
function backtrack(start, temp) {
if (temp.length === k) {
result.push([...temp]);
return;
}
for (let i = start; i < arr.length; i++) {
temp.push(arr[i]);
backtrack(i + 1, temp);
temp.pop();
}
}
backtrack(0, []);
return result;
}
const combos = combinations(indices, k);
let minNum = null;
for (const removeIndices of combos) {
const removeSet = new Set(removeIndices);
let candidate = '';
for (let i = 0; i < n; i++) {
if (!removeSet.has(i)) candidate += num[i];
}
candidate = candidate.replace(/^0+/, '');
if (candidate === '') candidate = '0';
if (minNum === null || candidate < minNum) minNum = candidate;
}
return minNum;
}
// Driver
console.log(removeKdigits("1432219", 3)); // Expected: "1219"
Line Notes
if (k === n) return "0";Return '0' if all digits removed
function combinations(arr, k)Generate all combinations of indices to remove
candidate = candidate.replace(/^0+/, '');Remove leading zeros from candidate
if (minNum === null || candidate < minNum) minNum = candidate;Track lex smallest candidate
TimeO(n choose k * n)
SpaceO(n choose k * n)
We generate all combinations of k indices to remove (n choose k), and for each, build a candidate string of length up to n.
💡 For n=10 and k=3, this means thousands of combinations and millions of operations, which is impractical for large inputs.
Interview Verdict: TLE
This approach is too slow for large inputs but is useful to understand the problem and correctness before optimizing.