Leetcode日练笔记38 [二叉树专题] #102 Binary Tree Level Order Traversal

#102 Binary Tree Level Order Traversal

Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level).

Example 1:

Leetcode日练笔记38 [二叉树专题] #102 Binary Tree Level Order Traversal_第1张图片

Input: root = [3,9,20,null,null,15,7]
Output: [[3],[9,20],[15,7]]

Example 2:

Input: root = [1]
Output: [[1]]

Example 3:

Input: root = []
Output: []
 

Iterative的解题思路:

这题有两个难点。

1:如何能按层来从上到下从左到右地顺序打印

2:如何能把打印的结果按层以list的形式打包在一起来打印

第一个问题。

如果先考虑最小单元的情况,一个母节点带两个子叶。打印顺序就是先母再左后右。

如果子叶还带子叶,打印顺序再叠加新子叶层。

这里【打印】的动作只能和【判断节点是否有子叶】的动作拆分开来,因为前者是需要root.val,后者需要的数据type是node。如果有子叶还要把信息再存入待打印的队伍里。

按照存入和打印的先后关系,我们应该用FIFO的queue。

最初给定一个母节点的时候,如果第一步先【判断节点是否有子叶】,那么新储存的子叶信息会和这个母节点混在一起,造成最后打印的时候无法以层为单位(以list的形式)而分开。所以我们要单独创建一个temp的变量,与【用来储存信息的queue】区别开来,专门用于处理节点【判断它们是否有子叶】。每个节点判断完之后,该存的子叶信息存进了queue之后,提取值,放入待打印的队列。当temp的节点全部处理完、清空之后,再一次性把所有待打印的队列append给res。再将queue里新一层的子叶全部转移给temp。

可以把queue想象成仓库,temp相当于作业间,最后res就是打包区。

temp作业间再分两个区,temp_node是专门放节点的, temp_val是放待打印的值。

在确保给到点不是None之后,预先把root放进queue里。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root: return root
        
        queue = [root]
        temp_node = []
        temp_val = []
        res = []
        
        while queue or temp_node:
            # swap queue and temp
            temp_node, queue = queue, temp_node
            while temp_node:
                root = temp_node.pop(0)
                temp_val.append(root.val)
                if root.left: queue.append(root.left)
                if root.right: queue.append(root.right)
            res.append(temp_val)
            temp_val = []
                    
        return res

runtime:

Leetcode日练笔记38 [二叉树专题] #102 Binary Tree Level Order Traversal_第2张图片

 Recursive的解题思路(说实话还是不太能想出来,虽然能看懂答案)

最简的base case就是先创建一个[],然后把母值加进去,再进入下一个循环,创建下一层的[],然后把原来的左叶右叶的值带进去。所以input除了母节点之外,还有层的信息。

recursive这里借助了一个helper(root, level)

Leetcode日练笔记38 [二叉树专题] #102 Binary Tree Level Order Traversal_第3张图片

试着写一遍:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        levels = []
        def helper(root, level):
            if not root: return root
            
            # create a new layer
            if level == len(levels):
                levels.append([]) 
                
            # append the value of the root
            levels[level].append(root.val)
            level += 1
            
            if root.left: helper(root.left, level)
            if root.right: helper(root.right, level)
            
        helper(root, 0)
        return levels

runtime:

Leetcode日练笔记38 [二叉树专题] #102 Binary Tree Level Order Traversal_第4张图片 

 

你可能感兴趣的:(leetcode日练,leetcode,算法,数据结构,python)