Repository navigation
Expand file tree
/
Copy pathpermutations.py
More file actions
54 lines (40 loc) · 1.96 KB
/
Copy pathpermutations.py
File metadata and controls
54 lines (40 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from typing import List
class Solution:
"""LeetCode #46 - Permutations (Medium)
https://leetcode.com/problems/permutations/
Return every ordering of `nums` (all values distinct). There are n! of them.
"""
def permute(self, nums: List[int]) -> List[List[int]]:
"""Backtracking over positions, with a `used` flag per element.
Key insight and the contrast worth understanding: in Subsets and
Combination Sum we passed a `start` index to *forbid* looking backwards,
because order did not matter there. Here order is the entire point, so
every branch must consider **all** elements - and the only thing to
exclude is an element already placed in the current permutation. That is
what `used` tracks.
A permutation is complete when its length reaches n; at that moment
every element has been used exactly once.
Same choose / explore / undo rhythm, except now two pieces of state get
restored on the way out - the list and the flag. Forgetting
`used[i] = False` is the classic bug: it silently produces only one
permutation.
Time: O(n * n!) - n! permutations, each copied in O(n).
Space: O(n) - recursion depth, the flags and the working list.
"""
result = []
current = []
used = [False] * len(nums)
def backtrack() -> None:
if len(current) == len(nums):
result.append(current[:]) # snapshot, not a reference
return
for i in range(len(nums)):
if used[i]:
continue # already placed in this permutation
used[i] = True # choose
current.append(nums[i])
backtrack() # explore
current.pop() # undo - both pieces of state
used[i] = False
backtrack()
return result