[英]DFS problem solving with recursion how does it work?
問題來了
有 n 個非負整數。 我們想適當地添加或減去這些數字以制作我們的目標數字。 例如,要使 [1, 1, 1, 1, 1] 中的數字為 3,可以使用以下五種方法:
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
編寫求解函數,以數組編號、目標編號和目標作為參數時,通過適當加減數字來返回生成目標編號的方法數。
限制
輸入/輸出示例
numbers: [1,1,1,1,1]
target: 3
return: 5
方法
1
/ \
-1 1
/ \ / \
-1 1 -1 1
-1 1 1 3
以 DFS 方式找到了這種方法,檢查所有情況,如果數字的組合等於目標數,則加法或減法然后計數。
代碼如下:
def solution(numbers, target):
total = 0
num_len = len(numbers)
def dfs(index=0):
if index < num_len:
numbers[index] *= 1
print('positive / index', index, numbers)
dfs(index + 1)
numbers[index] *= -1
print('negative / index', index, numbers)
dfs(index + 1)
else:
if sum(numbers) == target:
nonlocal total
total += 1
print('matched / index', index, numbers)
dfs()
return total
但是,我想知道它是如何運行的,控制台日志也是如此。
positive / index 0 [1, 1, 1, 1, 1]
positive / index 1 [1, 1, 1, 1, 1]
positive / index 2 [1, 1, 1, 1, 1]
positive / index 3 [1, 1, 1, 1, 1]
positive / index 4 [1, 1, 1, 1, 1]
negative / index 4 [1, 1, 1, 1, -1]
matched / index 5 [1, 1, 1, 1, -1]
negative / index 3 [1, 1, 1, -1, -1] ### how come this index all of sudden becomes 3? ###
positive / index 4 [1, 1, 1, -1, -1]
...
我有點理解遞歸索引的增量直到匹配/索引 5 但不太確定為什么下次它變成 3。
日志格式可能會讓您感到困惑。 5 之后,不再進行遞歸調用,因此下一個打印行與舊堆棧幀相關聯,該堆棧幀在探索下一個遞歸調用鏈之前一直在等待其子級解析。
如果添加縮進,您將更清楚地看到父子關系:
print(" " * index + 'positive', numbers)
0 1 2 3 4 5 stack depth
===========================
positive [1, 1, 1, 1, 1]
positive [1, 1, 1, 1, 1]
positive [1, 1, 1, 1, 1]
positive [1, 1, 1, 1, 1]
positive [1, 1, 1, 1, 1]
negative [1, 1, 1, 1, -1]
matched [1, 1, 1, 1, -1]
negative [1, 1, 1, -1, -1] <-- here's the call you asked about
... calls continue ...
在這里,您可以看到您的問題所涉及的否定分支回到了深度 3 並且不是matched
的子分支。 在matched
調用之后,沒有更多的子節點要探索,堆棧彈出回到父節點,父節點也沒有進一步的節點要探索,並在深度 2 彈出回到它的父節點,它仍然有它的negative
子調用鏈要探索,它確實產生了對深度 3 的第二次調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.