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]
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:
- Pick one element → Fix it at the end of the current permutation.
- Recurse on the remaining array → Generate permutations for the rest.
- 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].
- Remove
1, callpermute([2, 3]).
- This generates
[2,3]and[3,2]. -
Add back
1→[2,3,1],[3,2,1].- Restore
1. Now remove2, callpermute([1, 3]).
- Restore
Generates
[1,3]and[3,1].-
Add back
2→[1,3,2],[3,1,2].- Restore
2. Now remove3, callpermute([1, 2]).
- Restore
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;
};
Complexity Analysis
Time Complexity:
Each permutation hasnelements, and there aren!permutations.
→ O(n × n!)-
Space Complexity:
- The recursion stack goes as deep as
n. - The result array holds
n!permutations, each of sizen. → O(n × n!) space as well.
- The recursion stack goes as deep as
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)