这里记录一个小经验吧,关于dfs的原理和更多实践可以看:
https://blog.csdn.net/weixin_42001089/article/details/83001841
在处理树问题的时候,一般要使用dfs进行遍历,遍历函数的参数有时候需要母亲节点和孩子节点
即如下形式:
def dfs(parent,child):
pass
比如我们定义好了该dfs函数,在之后的递归调用中可以方便的使用:
def dfs(parent,child):
.....
dfs(child,child.left)
dfs(child,child.right)
现在有个小问题就是怎么调用,我们假设根节点是root,容易想到的是:
dfs(root,root.left)
dfs(root,root.right)
弄不好还的先判断一下其孩子有没有存在即:
if root.left:
dfs(root,root.left)
if root.right:
dfs(root,root.right)
其实这里有的时候不必这样,直接写成一个调用函数即可:
dfs(None,root)
只不过在定义dfs内部的时候,大概需要这样:
def dfs(parent,child):
if parent and child:
pass
if child.left:
dfs(child,child.left)
if child.right:
dfs(child,child.right)
下面是leetcode一个例题:思路是讨论区一个大神的,只不过正好说明了上面的问题,所以这里就看一下具体的实践吧
863. All Nodes Distance K in Binary Tree
扫描二维码关注公众号,回复:
4116044 查看本文章
class Solution(object):
def distanceK(self, root, target, K):
"""
:type root: TreeNode
:type target: TreeNode
:type K: int
:rtype: List[int]
"""
import collections
dict = collections.defaultdict(list)
def dfs(parent,child):
if parent and child:
dict[parent.val].append(child.val)
dict[child.val].append(parent.val)
if child.left:
dfs(child,child.left)
if child.right:
dfs(child,child.right)
dfs(None,root)
scope = [target.val]
seen = set(scope)
for i in range(K):
scope = [y for x in scope for y in dict[x] if y not in seen]
seen|=set(scope)
return scope
大体思路就是先dfs遍历得到dict,其key键是每一个节点值,其value值是一个列表,里面记录的是和key相邻的所有节点值
接着就是从目的节点不断向外搜索(每次相当于向外走一步,走K步正好就是达到我们想要的结果值),seen记录的是我们走过的值,scope记录的是每向外走一步所达到的所有元素集合