二叉樹思考——一套模板解決所有遍歷相關題

最近連續做了一些二叉樹的遍歷題,現在總結下規律

題目

在leetcode中

  1. 層次遍歷1:給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。
  2. 層次遍歷2:給定一個二叉樹,返回其節點值自底向上的層次遍歷。 (即按從葉子節點所在層到根節點所在的層,逐層從左向右遍歷)
  3. 路徑和1:給定一個二叉樹和一個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。
  4. 路徑和2:給定一個二叉樹和一個目標和,找到所有從根節點到葉子節點路徑總和等於給定目標和的路徑。

解析

其實這四道題,本質都是一個,就是遍歷二叉樹節點,只是3,4題在遍歷的時候會需要記錄值,所以只要做完第一題,其他題在這個基礎上改一改即可!

層次遍歷
例如:
給定二叉樹: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
返回其層次遍歷結果:

[
  [3],
  [9,20],
  [15,7]
]

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

解題框架

如圖
在這裏插入圖片描述

代碼

按照解題步驟,如下代碼

判空

    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []

定義數據結構

    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        nodes=[root]
        res=[]

分析遍歷的循環和跳出條件 非常重要!!

    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        nodes=[root]
        res=[]
        while nodes:  # 從上到下遍歷
        	val=[]    # 記錄遍歷過的值
        	for i in range(len(nodes)):  #從左到右遍歷一層
        	res.append(val) # 將記錄完的值放入res中
         return res

完成循環,返回結果

    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        nodes=[root]
        res=[]
        while nodes:
            val=[]
            for i in range(len(nodes)):
                node=nodes.pop(0)
                val.append(node.val)
                if node.left:
                    nodes.append(node.left)
                if node.right:
                    nodes.append(node.right)
            res.append(val)
        return res

拓展題目

2. 層次遍歷2

給定一個二叉樹,返回其節點值自底向上的層次遍歷。 (即按從葉子節點所在層到根節點所在的層,逐層從左向右遍歷)

只需要將遍歷的結果res倒序輸出即可

	return res[::-1]

3. 路徑和1

給定一個二叉樹和一個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。

示例: 
給定如下二叉樹,以及目標和 sum = 22,

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \      \
        7    2      1
返回 true, 因爲存在目標和爲 22 的根節點到葉子節點的路徑 5->4->11->2。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/path-sum
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

思路稍稍修改如下
在這裏插入圖片描述

  def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if not root:
           return False
        nodes=[(root,sum-root.val),]
        res=[]
        while nodes:
            node,cur_sum=nodes.pop(0)
            if not node.left and not node.right and cur_sum==0:
                return True
            if node.left:
                nodes.append((node.left,cur_sum-node.left.val))
            if node.right:
                nodes.append((node.right,cur_sum-node.right.val))
        return False

4. 路徑和2

給定一個二叉樹和一個目標和,找到所有從根節點到葉子節點路徑總和等於給定目標和的路徑。
只需要

	nodes=[(root,[root.val])]

其中[root.val],表示當節點到達root時,路徑爲[root.val],其他節點亦如此
同時,由於我們不再記錄sum,(要記錄也可以),所以我們最後直接比較路徑和與sum的值相等作爲正確條件

代碼如下

    def pathSum(self, root: TreeNode, sum_: int) -> List[List[int]]:
        res=[]
        if not root:
            return res
        nodes=[(root,[root.val]),]
        while nodes:
            node,tmp=nodes.pop(0)
            if not node.left and not node.right and sum(tmp)==sum_:
                res.append(tmp)
            if node.left:
                nodes.append((node.left,tmp+[node.left.val]))
            if node.right:
                nodes.append((node.right,tmp+[node.right.val]))
        return res

總結

其實,幾乎所有關於二叉樹遍歷的題都可以通過這種方式解決,比如z字形層次遍歷,最小深度等等,你學會了嗎?

發佈了110 篇原創文章 · 獲贊 103 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章