1. 程式人生 > >dfs呼叫小經驗+All Nodes Distance K in Binary Tree實踐

dfs呼叫小經驗+All Nodes Distance K in Binary Tree實踐

這裡記錄一個小經驗吧,關於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

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記錄的是每向外走一步所達到的所有元素集合