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
Limiting duplicate character occurrence to once in JavaScript
In JavaScript, removing duplicate characters while maintaining lexicographical order requires a strategic approach. This problem asks us to keep only one occurrence of each character, choosing positions that result in the lexicographically smallest string.
Problem Statement
We need to write a JavaScript function that takes a string and returns a new string where each character appears only once. The key constraint is that the result must be lexicographically smallest among all possible combinations.
For example, with input 'cbacdcbc', the output should be 'acdb'.
Understanding the Algorithm
The solution uses a greedy approach:
- Find the rightmost position of each character
- Build the result by selecting characters that maintain lexicographical order
- Ensure all unique characters are included
Complete Solution
const str = 'cbacdcbc';
const removeDuplicates = (str = '') => {
if (str.length 0 &&
result[result.length - 1] > char &&
count[result[result.length - 1]] > 0) {
const removed = result.pop();
inResult.delete(removed);
}
result.push(char);
inResult.add(char);
}
return result.join('');
};
console.log(removeDuplicates(str));
console.log(removeDuplicates('bcabc')); // "abc"
console.log(removeDuplicates('cbacdcbc')); // "acdb"
acdb abc acdb
How It Works
The algorithm maintains a stack-based approach:
- Count frequencies: Track how many times each character appears
- Process each character: Decrease its count and check if it's already included
- Remove larger characters: Pop characters from result if they're larger than current character and appear again later
- Add current character: Push to result and mark as included
Step-by-Step Example
For input 'cbacdcbc':
// Demonstrating the process step by step
const debugRemoveDuplicates = (str) => {
const count = {};
for (let char of str) {
count[char] = (count[char] || 0) + 1;
}
console.log('Initial counts:', count);
const result = [];
const inResult = new Set();
for (let i = 0; i 0 &&
result[result.length - 1] > char &&
count[result[result.length - 1]] > 0) {
const removed = result.pop();
inResult.delete(removed);
console.log(`Removed '${removed}' from result`);
}
result.push(char);
inResult.add(char);
console.log(`Added '${char}' to result:`, result.join(''));
console.log('---');
}
return result.join('');
};
debugRemoveDuplicates('cbacdcbc');
Initial counts: { c: 4, b: 2, a: 1, d: 1 }
Processing 'c' at index 0
Remaining count: 3
Added 'c' to result: c
---
Processing 'b' at index 1
Remaining count: 1
Added 'b' to result: cb
---
Processing 'a' at index 2
Remaining count: 0
Removed 'b' from result
Removed 'c' from result
Added 'a' to result: a
---
Processing 'c' at index 3
Remaining count: 2
Added 'c' to result: ac
---
Processing 'd' at index 4
Remaining count: 0
Added 'd' to result: acd
---
Processing 'c' at index 5
Remaining count: 1
'c' already in result, skipping
Processing 'b' at index 6
Remaining count: 0
Added 'b' to result: acdb
---
Processing 'c' at index 7
Remaining count: 0
'c' already in result, skipping
acdb
Time and Space Complexity
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n) | Each character is pushed and popped at most once |
| Space | O(1) | Fixed space for 26 lowercase letters |
Conclusion
This greedy stack-based algorithm efficiently removes duplicate characters while maintaining lexicographical order. The key insight is using character frequency to decide when it's safe to remove characters from the result.
