DEV Community

Rakesh Reddy Peddamallu
Rakesh Reddy Peddamallu

Posted on

46. Permutations

Understanding Permutations in JavaScript (Step by Step)

Permutations are all the possible arrangements of a given set of numbers.
For example, if we have [1, 2, 3], the permutations are:

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
Enter fullscreen mode Exit fullscreen mode

The problem: Given an array of distinct numbers, generate all possible permutations.


The Approach

The trick to solving permutations is recursion + backtracking.
Let’s break down the intuition:

  1. Pick one element → Fix it at the end of the current permutation.
  2. Recurse on the remaining array → Generate permutations for the rest.
  3. Backtrack → Put the element back, so other branches can use it.

In our code:

  • We remove the first element using nums.shift().
  • Recursively call permute(nums) on the smaller array.
  • After recursion, we put the removed element (n) at the end of each permutation.
  • Then, restore the element (nums.push(n)) so the array goes back to its original state for the next iteration.

This ā€œremove, recurse, restoreā€ cycle is the backtracking part.


Walking Through an Example

Take nums = [1, 2, 3].

  1. Remove 1, call permute([2, 3]).
  • This generates [2,3] and [3,2].
  • Add back 1 → [2,3,1], [3,2,1].

    1. Restore 1. Now remove 2, call permute([1, 3]).
  • Generates [1,3] and [3,1].

  • Add back 2 → [1,3,2], [3,1,2].

    1. Restore 2. Now remove 3, call permute([1, 2]).
  • Generates [1,2] and [2,1].

  • Add back 3 → [1,2,3], [2,1,3].

Put it all together → 6 permutations āœ….


The Code

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permute = function (nums) {
    let result = [];

    // Base case: if there's only one element, return it
    if (nums.length === 1) {
        return [[...nums]]; // make a copy
    }

    // Explore each element
    for (let i = 0; i < nums.length; i++) {
        const n = nums.shift(); // remove first element
        const perms = permute(nums); // recurse on remaining

        // Add the removed element to each permutation
        for (const perm of perms) {
            perm.push(n);
            result.push(perm);
        }

        nums.push(n); // restore the element (backtrack)
    }

    return result;
};
Enter fullscreen mode Exit fullscreen mode

Complexity Analysis

  • Time Complexity:
    Each permutation has n elements, and there are n! permutations.
    → O(n Ɨ n!)

  • Space Complexity:

    • The recursion stack goes as deep as n.
    • The result array holds n! permutations, each of size n. → O(n Ɨ n!) space as well.

Key Takeaways

  • The algorithm uses recursion + backtracking.
  • At each step, we remove one element, generate permutations of the rest, then restore it.
  • The result naturally builds up to all n! permutations.

This is a classic recursive pattern that shows up in many backtracking problems like subsets, combinations, and word search puzzles.


Top comments (0)