最近連續做了一些二叉樹的遍歷題,現在總結下規律
題目
在leetcode中
- 層次遍歷1:給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。
- 層次遍歷2:給定一個二叉樹,返回其節點值自底向上的層次遍歷。 (即按從葉子節點所在層到根節點所在的層,逐層從左向右遍歷)
- 路徑和1:給定一個二叉樹和一個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。
- 路徑和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字形層次遍歷,最小深度等等,你學會了嗎?