主函數?combine
def combine(self, n: int, k: int) -> List[List[int]]:result = [] # 存放所有有效的組合self.backtracking(n, k, 1, [], result) # 從數字1開始搜索return result
- 作用:初始化并啟動回溯過程。
- 參數:
n=4
:數字范圍是1到4。k=2
:每個組合需要2個數字。
- 過程:
- 創建空列表?
result
?存儲結果。 - 調用?
backtracking
?開始遞歸搜索。
- 創建空列表?
回溯函數?backtracking
def backtracking(self, n, k, startIndex, path, result):if len(path) == k: # 終止條件:當前組合已選夠k個數result.append(path[:]) # 將當前組合存入結果returnfor i in range(startIndex, n + 1): # 遍歷可選數字path.append(i) # 選擇當前數字iself.backtracking(n, k, i + 1, path, result) # 遞歸處理下一個數字path.pop() # 回溯:撤銷選擇i
具體執行步驟(以?n=4, k=2
?為例)
1. 主函數調用?backtracking(4, 2, 1, [], result)
startIndex = 1
,?path = []
- 進入循環?
for i in range(1, 5)
:-
i = 1:
path.append(1)
?→?path = [1]
- 遞歸調用?
backtracking(4, 2, 2, [1], result)
:startIndex = 2
,?path = [1]
- 子循環?
for i in range(2, 5)
:- i = 2:
path.append(2)
?→?path = [1, 2]
-
path = [1] path.append(2) # path = [1,2] # 現在調用 backtracking(n,k,3,[1,2],result) # ↓ 進入新的遞歸層級 if len([1,2]) == 2: # 立刻觸發檢查!result.append([1,2])return # 直接返回,不會繼續后面的循環 # 回到上一層 path.pop() # path恢復為[1]
對下面的解釋
- 滿足?
len(path) == 2
:result.append([1, 2])
?→?result = [[1, 2]]
path.pop()
?→?path = [1]
?(回溯)
- i = 3:
path.append(3)
?→?path = [1, 3]
- 滿足?
len(path) == 2
:result.append([1, 3])
?→?result = [[1, 2], [1, 3]]
path.pop()
?→?path = [1]
?(回溯)
- i = 4:
path.append(4)
?→?path = [1, 4]
- 滿足?
len(path) == 2
:result.append([1, 4])
?→?result = [[1, 2], [1, 3], [1, 4]]
path.pop()
?→?path = [1]
?(回溯)
- i = 2:
- 子遞歸結束,返回上一層。
path.pop()
?→?path = []
?(回溯)
-
i = 2:
path.append(2)
?→?path = [2]
- 遞歸調用?
backtracking(4, 2, 3, [2], result)
:startIndex = 3
,?path = [2]
- 子循環?
for i in range(3, 5)
:- i = 3:
path.append(3)
?→?path = [2, 3]
- 滿足?
len(path) == 2
:result.append([2, 3])
?→?result = [[1, 2], [1, 3], [1, 4], [2, 3]]
path.pop()
?→?path = [2]
?(回溯)
- i = 4:
path.append(4)
?→?path = [2, 4]
- 滿足?
len(path) == 2
:result.append([2, 4])
?→?result = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4]]
path.pop()
?→?path = [2]
?(回溯)
- i = 3:
- 子遞歸結束,返回上一層。
path.pop()
?→?path = []
?(回溯)
-
i = 3:
path.append(3)
?→?path = [3]
- 遞歸調用?
backtracking(4, 2, 4, [3], result)
:startIndex = 4
,?path = [3]
- 子循環?
for i in range(4, 5)
:- i = 4:
path.append(4)
?→?path = [3, 4]
- 滿足?
len(path) == 2
:result.append([3, 4])
?→?result = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
path.pop()
?→?path = [3]
?(回溯)
- i = 4:
- 子遞歸結束,返回上一層。
path.pop()
?→?path = []
?(回溯)
-
i = 4:
path.append(4)
?→?path = [4]
- 遞歸調用?
backtracking(4, 2, 5, [4], result)
:startIndex = 5
?>?n = 4
,直接返回,不處理。
path.pop()
?→?path = []
?(回溯)
-