All questions

Permutations & Subsets

Premium

Permutations & Subsets

A permutation is one ordering of a collection, and a subset is any selection from it — from picking nothing up to picking everything. This question asks you to generate all of both for an array of distinct values: every permutation (there are n! of them) and every subset (the power set, 2^n of them), packaged on one object as permutationsSubsets = { permutations, subsets }. The reason to pair them is that a single backtracking template — choose an option, recurse, then undo the choice — produces both; only the meaning of a choice changes. See Permutation and Power set for background.

Signature

permutationsSubsets.permutations(arr)  // distinct items -> array of all n! orderings
permutationsSubsets.subsets(arr)       // distinct items -> array of all 2^n subsets

Both return an array of arrays; each inner array is a brand-new array.

Examples

permutationsSubsets.permutations([1, 2, 3]);
// six arrays, in some order:
// [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]

permutationsSubsets.subsets([1, 2, 3]);
// eight arrays, in some order:
// [], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]

Notes

  • Distinct elements — assume the input has no repeats. Duplicate values would produce repeated permutations and subsets and need extra logic to de-duplicate (out of scope; noted in the solution).
  • Fresh arrays — return brand-new arrays. Never hand back a reference to the input, and never reuse one inner array across results.
  • Empty inputpermutations([]) is [[]] (one empty ordering) and subsets([]) is [[]] (the empty array is the only subset). Both have exactly one element, not zero.
  • Order is free — the outer array may be in any order; a grader compares results as sets. Keep each subset's own elements in input order.
  • Counts grow fastn! and 2^n blow up quickly (10! is over three million), so this is meant for small n. No libraries — build both yourself.

FAQ

What is backtracking, and why does it generate both?
Backtracking builds a partial answer one choice at a time, recurses to extend it, then undoes the choice to try the next option — a choose / recurse / undo loop. Generating permutations and subsets are both 'make a sequence of choices' problems, so the same skeleton produces both; only what counts as a valid next choice, and when you record a result, differ.
How many permutations and subsets does an array have?
An array of n distinct items has n! permutations (n options for the first position, n-1 for the next, and so on) and 2^n subsets (each element is independently in or out). For three items that is 6 orderings and 8 subsets. Both counts grow fast, so these generators are meant for small n.
Why copy the path with slice() instead of storing it directly?
The running path is one array that is mutated in place as the recursion chooses and undoes options. Pushing it by reference would store the same array for every result, and you would watch them all empty out as the recursion unwinds. current.slice() snapshots the path at that moment so each result is independent.

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium