這題要做的是層級遍歷二元樹,從根節點開始一層一層讀取節點的值,要把每層的節點值按順序加到結果列中。
思路:
輸入,是一棵二元樹的根節點 root ,輸出, 返回一個二維列表,其中每個內部列表表該層節點的值,處理, 層次遍歷通常可以通過**廣度優先搜索(BFS)實現,用一個隊列輔助做遍歷。
步驟:
如果樹是空,直接返回空列表 [ ],用一個隊列來存每層的節點,從根節點開始,每次迭代,取出當前層的節點,然後把下一層的子節點(左、右子節點)加到隊列,每層結束後,把該層的節點值加到結果列表,重複上述過程直到隊列是空。
關鍵:
用隊列(Queue)**可以保證在一層處理完後,能再處理下一層,每層的節點遍歷完後,結果會加入一個新列表中。
程式碼:
#Definition for a binary tree node.
#class TreeNode(object):
#def init(self, val=0, left=None, right=None):
#self.val = val
#self.left = left
#self.right = right
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
#如果根節點是空的,直接返回空列表
if not root:
return []
#結果列表,存每層的結果
result = []
#用隊列來存每層的節點,初始時隊列中有根節點
queue = [root]
#當隊列不空時,遍歷
while queue:
# 存當前層所有節點的值
current_level = []
#當前層的節點數
level_size = len(queue)
#處理當前層的每個節點
for i in range(level_size):
# 從隊列中取最前面的節點
node = queue.pop(0)
#把該節點的值加到當前層結果中
current_level.append(node.val)
#把左子節點加到隊列,如果存在
if node.left:
queue.append(node.left)
#把右子節點加到隊列,如果存在
if node.right:
queue.append(node.right)
#把當前層的結果加到總結果中
result.append(current_level)
#返回最終結果
return result
解釋:
檢查根節點是不是空:,如果 root 是空的,表二元樹為空,直接返回空列表,初始化隊列,用 queue 存當前層的節點,初始時把根節點 root 放到隊列,BFS 遍歷,用 while 循環不斷處理隊列中的節點,每次迭代處理一層,current_level 用來存當前層的節點值,level_size 記錄當前層節點數量,方便迴圈處理該層的所有節點,把當前層的每個節點取出,再把它的值加入到current_level。
如果節點有左子節點或右子節點,把它加到隊列,方便下層處理,處理完一層後,把那層結果加到 result,每層結束後,把當前層結果 current_level 加到到 result 中,返回結果,當隊列處理完後,返回 result,其中每個內部列表表樹的一層。
用了 BFS,時間複雜度為 O(n),n 是樹中節點的數量,每個節點都被訪問一次。
心得:
這題用 BFS 的基本概念,熟悉處理樹結構的遍歷方法,也解釋怎麼用隊列在廣度優先搜尋裡實現層次遍歷的好例子,大二下對二元樹的理解有花時間,所以解決這題不會到太耗時。