Every ordering of the elements. At each level you pick any element not used yet, so the branching factor shrinks n, n-1, n-2, …, giving n! leaves.
Keep a used[] flag per element. At each recursion level, loop over all elements and branch into every one that's still free. Mark it used, recurse, then unmark.
When the path length hits n, you've built one full permutation.
void dfs(vector<int>& nums, vector<bool>& used,
vector<int>& path, vector<vector<int>>& out) {
if (path.size() == nums.size()) { // full permutation
out.push_back(path);
return;
}
for (int i = 0; i < nums.size(); i++) {
if (used[i]) continue; // skip already-placed
used[i] = true; // CHOOSE
path.push_back(nums[i]);
dfs(nums, used, path, out); // EXPLORE
path.pop_back(); // UNCHOOSE
used[i] = false;
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> out;
vector<int> path;
vector<bool> used(nums.size(), false);
dfs(nums, used, path, out);
return out; // n! permutations
}
n! permutations, each length n to copy into the output.
Recursion depth, path, and the used[] flag array.
Factorial growth, 3! = 6, 4! = 24, 5! = 120.
nums[i]==nums[i-1] && !used[i-1] to avoid identical permutations.