forked from keon/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpermute.py
More file actions
88 lines (66 loc) · 2.16 KB
/
permute.py
File metadata and controls
88 lines (66 loc) · 2.16 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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""
Permutations
Given a collection of distinct elements, return all possible permutations.
Reference: https://en.wikipedia.org/wiki/Permutation
Complexity:
Time: O(n * n!) where n is the number of elements
Space: O(n * n!) to store all permutations
"""
from __future__ import annotations
from collections.abc import Generator
def permute(elements: list | str) -> list:
"""Return all permutations of the given elements.
Args:
elements: A list or string of distinct elements.
Returns:
A list of all permutations (same type as input elements).
Examples:
>>> permute([1, 2, 3])
[[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]]
"""
if len(elements) <= 1:
return [elements]
result = []
for perm in permute(elements[1:]):
for i in range(len(elements)):
result.append(perm[:i] + elements[0:1] + perm[i:])
return result
def permute_iter(elements: list | str) -> Generator:
"""Yield all permutations of the given elements one at a time.
Args:
elements: A list or string of distinct elements.
Yields:
One permutation at a time (same type as input elements).
Examples:
>>> list(permute_iter([1, 2]))
[[1, 2], [2, 1]]
"""
if len(elements) <= 1:
yield elements
else:
for perm in permute_iter(elements[1:]):
for i in range(len(elements)):
yield perm[:i] + elements[0:1] + perm[i:]
def permute_recursive(nums: list[int]) -> list[list[int]]:
"""Return all permutations using DFS backtracking.
Args:
nums: A list of distinct integers.
Returns:
A list of all permutations.
Examples:
>>> sorted(permute_recursive([1, 2]))
[[1, 2], [2, 1]]
"""
result: list[list[int]] = []
_dfs(result, nums, [])
return result
def _dfs(
result: list[list[int]],
nums: list[int],
path: list[int],
) -> None:
"""DFS helper that builds permutations by choosing remaining elements."""
if not nums:
result.append(path)
for i in range(len(nums)):
_dfs(result, nums[:i] + nums[i + 1 :], path + [nums[i]])