Leetcode # 77. Combinations
- 2023.08.01
- ★★ Medium Backtracking Brute-Force Combination LeetCode Queue Recursion
https://leetcode.com/problems/combinations
Solution (Backtracking)
\begin{align}
&\text{Time Complexity: }O(k \cdot \text{C}^n_k)\\
&\text{Space Complexity: }O(k)\\
\end{align}
- _combine([1, 2, …, n – 1], k) 使用O(Cnk) 的 time complexity
之後分支的每一層所使用的 time complexity 越來越少
(_combine([1, 2, …, n – 1], k) → _combine([2, 3, …, n – 1], k) → _combine([3, 4, …, n – 1], k) → … )
time complexity 的上限為 k * O(Cnk) = O(k * Cnk) = n! / [(k – 1)! * (n – k)!] - 因為 output 所使用的空間不計入 space complexity
所以只有 recursion 使用的 O(k)
(recursion call stack 的最大 depth 為 k)
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
def _combine(l, k):
if k == 1:
return [[e] for e in l]
if k > len(l):
return []
return _combine(l[1:], k) + [[l[0]] + _l for _l in _combine(l[1:], k - 1)]
return _combine([i for i in range(1, n + 1)], k)
Solution (Queue)
Time Complexity: O(Cnk)
(加了 if n - cur[-1] + 1 < k - len(cur): continue
能排除掉剩餘數字已不夠構築長度為 k 的組合,大幅提升速度)
Space Complexity: O(k ** 2)
(每一輪的 queue 的最大 space complexity 為 len(cur) * (k – len(cur) + 1)
len(cur) 為 k / 2 時有最大值 (k / 2) * (k – k / 2 + 1) = (k ** 2) / 4 + (k / 2))
(The input and output generally do not count towards the space complexity.)
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
queue = collections.deque([[i] for i in range(1, n + 1)])
all_possible_combinations = []
while queue:
cur = queue.popleft()
if len(cur) == k:
all_possible_combinations.append(cur)
continue
if n - cur[-1] + 1 < k - len(cur): continue
for i in range(cur[-1] + 1, n + 1):
queue.append(cur + [i])
return all_possible_combinations
Last Updated on 2023/08/16 by A1go