Record 321 and finishOnly index 0 remains; append 1, copy [3,2,1], and restore every choice as recursion unwinds.
[]F,F,F[3]F,F,T[3,2]F,T,T[3,2,1]active callT,T,T
inputnums = [1, 2, 3]columnspath | used indicesactionsave 321; unwind and restore used=[F,F,F]result[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
Recognize it
Use this pattern when every ordering is required and each input position may appear exactly once in each complete path.
Keep true
At every choose call, used[index] is true exactly when nums[index] appears in path, path length is the next output position, and returning from a branch restores both structures to their entry state.
Reuse it
When choices are reusable across sibling branches but forbidden within one path, mark before recursion and unmark after return; index-based flags also handle equal values more safely than value membership.
Read it this way: choose() starts with path=[] and used=[F,F,F]; no permutation is complete yet. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.
Pattern: Backtracking with a used list.
Simple idea: At each position, try every value that is not already in the path. Remove it
after that branch finishes.
def permutations(nums: list[int]) -> list[list[int]]: answer: list[list[int]] = [] path: list[int] = [] used = [False] * len(nums) def choose() -> None: if len(path) == len(nums): answer.append(path.copy()) return for index, num in enumerate(nums): if not used[index]: used[index] = True path.append(num) choose() path.pop() used[index] = False choose() return answer