day15| 层序遍历;101. 对称二叉树;226. 翻转二叉树

102. 二叉树的层序遍历

 

实现思路

1. 利用队列实现

2. 先把根节点放入队列

3. 弹出根节点并读取根节点的值,存入result列表中

4. 判断根节点是否有左右孩子,按顺序存入队列中

5. 进入下一个循环

 

代码如下:

class Solution:
    """二叉树层序遍历迭代解法"""

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

        from collections import deque
        que = deque([root])

        while que:
            size = len(que)
            result = []
            for _ in range(size):
                cur = que.popleft()
                result.append(cur.val)
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
            results.append(result)

        return results

 

 

107. 二叉树的层序遍历II

 

思路:

上一题最后一句改为return results[::-1]即可

 

 

199. 二叉树的右视图

 

思路:

利用前述代码,从上到下,从左至右遍历,但是只保存每层的最后一个值即可

# 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 rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        results=[]
        if not root:
            return results
        
        que=collections.deque([root])

        while que:
            n=len(que)
            for i in range(n):
                cur=que.popleft()
                if i==n-1:
                    results.append(cur.val)
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
        
        return results

 

 

637. 二叉树的层平均值

 

思路:

还是用前几题代码,最后求个平均值再加入到results中即可

 

代码如下:

# 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 averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
        results = []
        if not root:
            return results

        from collections import deque
        que = deque([root])

        while que:
            size = len(que)
            result = []
            for _ in range(size):
                cur = que.popleft()
                result.append(cur.val)
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
            results.append(sum(result)/size)

        return results

 

429. N叉树的层序遍历

 

这里主要要搞懂Node里面是什么结构,children是什么结构,children是一个列表,里面存有Node

 

思路:

还是借用前几题的代码实现;把新的一层的节点都加到队列最后边

 

代码如下:

"""
# Definition for a Node.
class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution:
    def levelOrder(self, root: 'Node') -> List[List[int]]:
        results=[]
        if not root:
            return results
        
        que=collections.deque([root])

        while que:
            size=len(que)
            result=[]
            for _ in range(size):
                cur=que.popleft()
                result.append(cur.val)

                for child in cur.children:
                    que.append(child)
            
            results.append(result)
        
        return results

 

515. 在每个树行中找最大值

 

和层平均值一样,max(result)即可

 

# 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 averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
        results = []
        if not root:
            return results

        from collections import deque
        que = deque([root])

        while que:
            size = len(que)
            result = []
            for _ in range(size):
                cur = que.popleft()
                result.append(cur.val)
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
            results.append(max(result))

        return results

 

 

116. 填充每个节点的下一个右侧节点指针

思路:

1. 利用层序遍历

2. 首先将第1个节点放入队列中,进行层遍历,如果i小于size-1,则令节点next指针等于que[0],刚好可以实现next指针指向右侧节点;

3. 如果等于size-1,说明是每层最右边的节点,因为next默认值是null,也就没必要赋值为que[0]了,此时的que[0]是下一层第1个节点

代码如下:

import collections 

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        
        if not root:
            return root
        
        # 初始化队列同时将第一层节点加入队列中,即根节点
        Q = collections.deque([root])
        
        # 外层的 while 循环迭代的是层数
        while Q:
            
            # 记录当前队列大小
            size = len(Q)
            
            # 遍历这一层的所有节点
            for i in range(size):
                
                # 从队首取出元素
                node = Q.popleft()
                
                # 连接
                if i < size - 1:
                    node.next = Q[0]
                
                # 拓展下一层节点
                if node.left:
                    Q.append(node.left)
                if node.right:
                    Q.append(node.right)
        
        # 返回根节点
        return root

 

 

117. 填充每个节点的下一个右侧节点指针II

 

思路:

同上题代码

"""
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        
        # 初始化队列同时将第一层节点加入队列中,即根节点
        Q = collections.deque([root])
        
        # 外层的 while 循环迭代的是层数
        while Q:
            
            # 记录当前队列大小
            size = len(Q)
            
            # 遍历这一层的所有节点
            for i in range(size):
                
                # 从队首取出元素
                node = Q.popleft()
                
                # 连接
                if i < size - 1:
                    node.next = Q[0]
                
                # 拓展下一层节点
                if node.left:
                    Q.append(node.left)
                if node.right:
                    Q.append(node.right)
        
        # 返回根节点
        return root

 

104. 二叉树最大深度

 

还是利用之前的层序遍历代码;

1. 每次进入循环,都给results加1

 

代码如下:

 

class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        results = 0
        if not root:
            return results

        que = deque([root])

        while que:
            size = len(que)
            results+=1
            for _ in range(size):
                cur = que.popleft()
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)

        return results

 

111. 二叉树的最小深度

 

还是利用层序遍历,当某个节点左孩子和有孩子都没有,直接返回当前的results

 

代码如下:

# 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 minDepth(self, root: Optional[TreeNode]) -> int:
        results = 0
        if not root:
            return results

        que = deque([root])

        while que:
            size = len(que)
            results+=1
            for _ in range(size):
                cur = que.popleft()
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
                if not cur.left and not cur.right:
                    return results

        return results

 

以上都是层序遍历的应用题目

---------------------------------

 

226. 翻转二叉树

 

思路:

1. 交换头结点的左右孩子

2. 递归实现交换左右孩子的左右孩子

3. 停止条件为root为null

 

代码如下:

# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        # 递归函数的终止条件,节点为空时返回
        if not root:
            return
        # 将当前节点的左右子树交换
        root.left,root.right = root.right,root.left
        # 递归交换当前节点的 左子树和右子树
        self.invertTree(root.left)
        self.invertTree(root.right)
        # 函数返回时就表示当前这个节点,以及它的左右子树
        # 都已经交换完了        
        return root

 

101. 对称二叉树

 

代码如下:

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        def dfs(left,right):
            # 递归的终止条件是两个节点都为空
            # 或者两个节点中有一个为空
            # 或者两个节点的值不相等
            if not (left or right):
                return True
            if not (left and right):
                return False
            if left.val!=right.val:
                return False
            return dfs(left.left,right.right) and dfs(left.right,right.left)
        # 用递归函数,比较左节点,右节点
        return dfs(root.left,root.right)

 

 

总结

1. 递归好难

posted @ 2023-04-02 20:55  blueCP1999  阅读(17)  评论(0)    收藏  举报