原题目
DFS铁憨憨理解:
该题解前面的话完全看不懂(水平不够)。
但理解了下面这句话:
每次深入的结果,就是d[(i, cur)] = dfs(cur + nums[i], i + 1, d) + dfs(cur - nums[i], i + 1, d)。
原作者对这句话是这样解释的:
意思就是当前节点推导到最后有多少个可能性呢?这个节点再读取一位,要么是加上这一位,要么是减掉这一位,所以这个节点的可能性就是对加上下一位的可能性与减掉下一位的可能性之和。
铁憨憨当是没法理解,但后来从代码中理解了。
此处便是递归的真谛,把大问题分解成小问题。
以原例:
nums: [1, 1, 1, 1, 1], S: 3
但这个递归确实是没得想到:
大问题:
d(0, 0)为多少?前面的 0 为当前的总和,后面的 0 为当前正在与 第 0 位做判断。
小问题:理解:
if i < len(nums) and (cur, i) not in d: # 搜索周围节点
d[(cur, i)] = dfs(cur + nums[i], i + 1, d) + dfs(cur - nums[i],i + 1, d)
d(0, 0) = d(0 + 1, 1) + d(0 - 1, 1) => d(0, 0) = d(1, 1) + d(-1, 1)
d(1, 1) = d(1 + 1, 2) + d(1 - 1, 2) => d(1, 1) = d(2, 2) + d(0, 2)
d(2, 2) = d(2 + 1, 3) + d(2 - 1, 1) => d(2, 2) = d(3, 3) + d(1, 3)
d(3, 3) = d(3 + 1, 4) + d(3 - 1, 4) => d(3, 3) = d(4, 4) + d(2, 4)
d(4, 4) = d(4 + 1, 5) + d(4 - 1, 1) => d(4, 4) = d(5, 5) + d(3, 5)
递归是要有个尽头的,不然无限递归。理解:
return d.get((cur, i), int(cur == S))
在这题中显然就是在第 5 位的时候进行判断,所以当递归到最深处时,需要进行返回结果,如果是目标值,则返回 1 ,即这是 1 种路径, 如果没有,则返回 0:
d(4, 4) = d(5, 5) + d(3, 5) => d(4, 4) = 0+ 1 = 1
然后当你(对自己说的)回来看的时候还不懂的时候,你就是个十足的铁憨憨了!!!