Creating all possible unique permutations of a string in JavaScript

We are required to write a JavaScript function that takes in a string str. Our function should create all permutations of the input string and remove duplicates, if present. This means, we have to shuffle all letters from the input in all possible orders.

Problem

When generating permutations of strings with repeated characters, we need to avoid duplicate permutations. For example, the string "aabb" should not generate identical permutations like "aabb" appearing multiple times.

Algorithm Approach

The solution uses recursion with duplicate checking:

  • For each character position, try placing each unique character
  • Skip duplicate characters at the same position using indexOf()
  • Recursively generate permutations for the remaining characters
  • Combine the current character with all permutations of the remainder

Implementation

const str = 'aabb';
const permute = (str = '') => {
    if (!!str.length && str.length < 2) {
        return str
    }
    const arr = [];
    for (let i = 0; i < str.length; i++) {
        let char = str[i]
        if (str.indexOf(char) != i)
            continue
        let remainder = str.slice(0, i) + str.slice(i + 1, str.length)
        for (let permutation of permute(remainder)) {
            arr.push(char + permutation)
        }
    }
    return arr
}
console.log(permute(str));
[ 'aabb', 'abab', 'abba', 'baab', 'baba', 'bbaa' ]

How It Works

The function works by:

  1. Base case: If string length is less than 2, return the string itself
  2. Character selection: For each position, select the first occurrence of each unique character
  3. Duplicate avoidance: str.indexOf(char) != i skips duplicate characters
  4. Recursive call: Generate permutations for the remaining string after removing the selected character
  5. Combination: Prepend the selected character to each permutation of the remainder

Alternative Implementation with Set

Here's another approach using a Set to eliminate duplicates:

const permuteWithSet = (str) => {
    if (str.length <= 1) return [str];
    
    const result = new Set();
    
    for (let i = 0; i < str.length; i++) {
        const char = str[i];
        const remaining = str.slice(0, i) + str.slice(i + 1);
        const perms = permuteWithSet(remaining);
        
        for (const perm of perms) {
            result.add(char + perm);
        }
    }
    
    return Array.from(result);
};

console.log(permuteWithSet('aabb'));
[ 'aabb', 'abab', 'abba', 'baab', 'baba', 'bbaa' ]

Testing with Different Inputs

console.log('Permutations of "abc":', permute('abc'));
console.log('Permutations of "aab":', permute('aab'));
console.log('Permutations of "a":', permute('a'));
Permutations of "abc": [ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ]
Permutations of "aab": [ 'aab', 'aba', 'baa' ]
Permutations of "a": a

Conclusion

The recursive approach efficiently generates unique permutations by skipping duplicate characters at each level. This prevents redundant calculations and ensures all permutations are distinct, making it ideal for strings with repeated characters.

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

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements