Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Selected Reading
Smallest number after removing n digits in JavaScript
We need to write a JavaScript function that removes n digits from a number to make it as small as possible. This is a classic greedy algorithm problem that uses a stack-based approach.
Problem Statement
Given a number string m and an integer n, remove n digits from m to create the smallest possible number.
For example:
Input: m = '45456757', n = 3 Output: '44557'
We remove digits 5, 6, and 7 to get the smallest result.
Algorithm Approach
We use a greedy algorithm with a stack:
- Process digits left to right (leftmost positions are most valuable)
- Remove larger digits from the stack when a smaller digit appears
- Keep the smallest possible digits in leftmost positions
Implementation
const m = '45456757';
const n = 3;
const removeDigits = (m, n, stack = []) => {
let arr = m.split('').map(Number);
for(let el of arr){
// Remove larger digits from stack while we can
while (n && stack.length && el < stack[stack.length - 1]){
stack.pop();
--n;
};
stack.push(el);
};
// Find first non-zero digit to avoid leading zeros
let begin = stack.findIndex(el => el > 0);
let end = stack.length - n;
// Handle edge cases: empty result, all zeros, or invalid range
return (!stack.length || begin == -1 || begin >= end) ? "0" :
stack.slice(begin, end).join('');
};
console.log(removeDigits(m, n));
44557
Step-by-Step Execution
For input '45456757' with n=3:
const traceExecution = (m, n) => {
let stack = [];
let arr = m.split('').map(Number);
let removals = n;
console.log('Processing digits:', arr);
for(let i = 0; i < arr.length; i++){
let el = arr[i];
console.log(`\nProcessing digit: ${el}`);
while (removals && stack.length && el < stack[stack.length - 1]){
let removed = stack.pop();
console.log(` Removed ${removed} (${el} < ${removed})`);
--removals;
}
stack.push(el);
console.log(` Stack now: [${stack.join(', ')}], removals left: ${removals}`);
}
return stack.slice(0, stack.length - removals).join('');
};
console.log('\nFinal result:', traceExecution('45456757', 3));
Processing digits: [ 4, 5, 4, 5, 6, 7, 5, 7 ] Processing digit: 4 Stack now: [4], removals left: 3 Processing digit: 5 Stack now: [4, 5], removals left: 3 Processing digit: 4 Removed 5 (4 < 5) Stack now: [4, 4], removals left: 2 Processing digit: 5 Stack now: [4, 4, 5], removals left: 2 Processing digit: 6 Stack now: [4, 4, 5, 6], removals left: 2 Processing digit: 7 Stack now: [4, 4, 5, 6, 7], removals left: 2 Processing digit: 5 Removed 7 (5 < 7) Removed 6 (5 < 6) Stack now: [4, 4, 5, 5], removals left: 0 Processing digit: 7 Stack now: [4, 4, 5, 5, 7], removals left: 0 Final result: 44557
Edge Cases
// Test edge cases
console.log('Remove all digits:', removeDigits('123', 3));
console.log('Leading zeros:', removeDigits('10200', 1));
console.log('All same digits:', removeDigits('1111', 2));
Remove all digits: 0 Leading zeros: 200 All same digits: 11
Conclusion
This greedy algorithm efficiently finds the smallest number by maintaining smaller digits in more significant positions. The stack ensures we always keep the optimal digits while processing left to right.
Advertisements
