function subsets(nums) {const res = [], path = [];
function backtrack(start) {res.push([...path]);
for (let i = start; i < nums.length; i++) {path.push(nums[i]);
backtrack(i + 1);
path.pop(); // undo
}
}
backtrack(0);◄
return res;
}
Each element has exactly two fates: in the subset or out of it. That gives 2ⁿ subsets — and backtracking walks that decision tree.
Carry a running path (the subset built so far). Every state of the path is itself a valid subset, so record it the moment you enter a call — no special base case needed.
Then, for each remaining element, choose it (push), explore deeper (recurse from i + 1 so you never reuse or reorder), and un-choose it (pop).
That pop is the backtrack: it rewinds the path so the next branch starts from a clean state.