Removing adjacent duplicates from a string in JavaScript

In JavaScript, removing adjacent duplicate characters from a string involves iterating through the string and eliminating consecutive identical characters until no more duplicates remain. This problem is commonly solved using a stack-based approach.

Problem Statement

Given a string, we need to repeatedly remove adjacent duplicate characters until no more adjacent duplicates exist. For example, with the string 'kllkmk', we first remove 'll' to get 'kkmk', then remove 'kk' to get the final result 'mk'.

Algorithm Approach

We use a stack (array) to track characters. When we encounter a character that matches the top of the stack, we remove all occurrences of that character from the stack. Otherwise, we add the character to the stack.

Example Implementation

const str = 'kllkmk';

const removeDuplicates = (str = '') => {
    const stack = [];
    
    for (const char of str) {
        if (char === stack[stack.length - 1]) {
            // Remove all consecutive duplicates from stack
            while (stack[stack.length - 1] === char) {
                stack.pop();
            }
        } else {
            // Add character to stack
            stack.push(char);
        }
    }
    
    return stack.join('');
};

console.log(removeDuplicates(str));
mk

Step-by-Step Execution

Let's trace through the example 'kllkmk':

const traceRemoval = (str) => {
    const stack = [];
    console.log(`Processing: "${str}"`);
    
    for (let i = 0; i < str.length; i++) {
        const char = str[i];
        console.log(`\nStep ${i + 1}: Character '${char}'`);
        console.log(`Stack before: [${stack.join(', ')}]`);
        
        if (char === stack[stack.length - 1]) {
            while (stack[stack.length - 1] === char) {
                stack.pop();
            }
            console.log(`Removed duplicates`);
        } else {
            stack.push(char);
            console.log(`Added '${char}'`);
        }
        
        console.log(`Stack after: [${stack.join(', ')}]`);
    }
    
    const result = stack.join('');
    console.log(`\nFinal result: "${result}"`);
    return result;
};

traceRemoval('kllkmk');
Processing: "kllkmk"

Step 1: Character 'k'
Stack before: []
Added 'k'
Stack after: [k]

Step 2: Character 'l'
Stack before: [k]
Added 'l'
Stack after: [k, l]

Step 3: Character 'l'
Stack before: [k, l]
Removed duplicates
Stack after: [k]

Step 4: Character 'k'
Stack before: [k]
Removed duplicates
Stack after: []

Step 5: Character 'm'
Stack before: []
Added 'm'
Stack after: [m]

Step 6: Character 'k'
Stack before: [m]
Added 'k'
Stack after: [m, k]

Final result: "mk"

Alternative Approaches

Method Time Complexity Space Complexity Best For
Stack-based O(n) O(n) Single pass solution
Recursive O(n²) O(n) Simple logic, less efficient

Edge Cases

// Test various edge cases
const testCases = ['', 'a', 'aa', 'abc', 'aabbcc', 'abccba'];

testCases.forEach(test => {
    console.log(`"${test}" ? "${removeDuplicates(test)}"`);
});
"" ? ""
"a" ? "a"
"aa" ? ""
"abc" ? "abc"
"aabbcc" ? ""
"abccba" ? ""

Conclusion

The stack-based approach efficiently removes adjacent duplicates in O(n) time complexity. Each character is processed once, making it optimal for this problem type.

Updated on: 2026-03-15T23:19:00+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements