代码随想录算法训练营第十五天| 层序遍历、LeetCode226.翻转二叉树 、LeetCode101.对称二叉树 2

一:层序遍历(代码随想录-层序遍历)

        先看看视频,理解怎么进行层序遍历(层序遍历视频讲解)

        理解之后,可以刷一下10道题:

  • 102.二叉树的层序遍历
  • 107.二叉树的层次遍历II
  • 199.二叉树的右视图
  • 637.二叉树的层平均值
  • 429.N叉树的层序遍历
  • 515.在每个树行中找最大值
  • 116.填充每个节点的下一个右侧节点指针
  • 117.填充每个节点的下一个右侧节点指针II
  • 104.二叉树的最大深度
  • 111.二叉树的最小深度

代码展示:

        Leetcode102.二叉树的层序遍历

# 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]]:
        # 层序遍历
        # 使用队列来实现
        queue = []
        res = []
        if not root:             # 当根节点为None时,直接返回空数组
            return res
        queue.append(root)       # 将根节点加入队列
        while queue:             # 当队列不为空时,遍历二叉树
            q_size = len(queue)   # 记录此时队列的长度,用来统计每层的节点数量
            q_list = []          # 用来记录这一层的节点
            while q_size > 0:                       # 当q_size不为0,说明这一层的节点还未遍历完,还剩q_size个节点
                node = queue.pop(0)                 # 弹出此时队列中的第一个节点
                q_list.append(node.val)             # 并将这个节点的值加入到一维数组中
                q_size -= 1                         # 弹出一个节点,本层所剩的节点减1
                # 弹出这个节点后,将这个节点的左右子节点加入到队列中,左右子节点为空则不加入
                if node.left:                       
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            # 当q_size为0时,说明一层的节点已经全部遍历完了,将这一层的一维数组添加到res中
            res.append(q_list)
        return res

        LeetCode107.二叉树的层次遍历II

# 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 levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
        # 层序遍历
        # 自底向上的层序遍历,可以先自上而下进行层序遍历,然后再将数组进行翻转
        queue = []
        res = []
        if not root:
            return res                    # 根节点为空,返回空数组
        queue.append(root)                # 根节点不为空,将根节点加入队列中
        while queue:
            q_size = len(queue)           # 统计每层的节点数
            q_list = []
            while q_size > 0:   
                node = queue.pop(0)       # 弹出队列的第一个节点
                q_list.append(node.val)   # 将弹出的节点的值,加入一维数组中
                q_size -= 1               # 本层剩余的节点的数减1
                # 将弹出节点的左右子节点加入队列,如果为空则不加入
                if node.left:
                    queue.append(node.left)     
                if node.right:
                    queue.append(node.right)
            # 当q_size为0时,同一层的节点已经遍历完,将存储同一层节点的一维数组加入res中
            res.append(q_list)
        # 得到的是自上而下的层序遍历,将数组翻转一下
        res = res[::-1]
        return res

        LeetCode199.二叉树的右视图

# 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]:
        queue = []
        res = []
        if not root:
            return res                    # 根节点为空则直接返回空数组
        queue.append(root)                # 根节点不为空,将根节点加入队列queue       
        while queue:                      
            q_len = len(queue)            # 记录每一层的节点数
            # 当每一层剩余节点数不为0时,把每层剩下的节点依次弹出,并把弹出节点的左右子节点加入队列queue
            while q_len > 0:              
                node = queue.pop(0)            # 弹出节点
                if q_len == 1:                 # 当每层剩下的节点数为1时,此时这个节点就是右侧能看到的节点
                    res.append(node.val)       # 把这个节点的值添加到res中
                q_len -= 1                     # 每弹出一个节点,这一层剩下的节点数就减1
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return res 

        LeetCode637.二叉树的层平均值

# 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]:
        # 层序遍历
        # 获取到每一层的所有节点的值,然后求平均值
        queue = []
        res = []
        if not root:
            return res                             # 根节点为空,则直接返回空数组
        queue.append(root)                         # 根节点不为空,将根节点加入队列queue
        while queue:
            q_len, n = len(queue), len(queue)      # 获取每层节点的数量
            q_sum = 0                              # 统计每层节点的值的总和
            while q_len > 0:
                node = queue.pop(0)                # 每层剩余的节点数不为空,弹出队列中的第一个节点
                q_sum += node.val                  # 将每个节点的值进行求和
                q_len -= 1                         # 弹出一个节点,剩余的节点数减1
                # 弹出节点的左右子节点不为空,则将左右子节点加入队列queue
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            # 对每层的节点进行求平均值
            avg = q_sum/n
            res.append(avg)
        return res

          LeetCode429.N叉树的层序遍历

"""
# 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]]:
        res = []
        if not root:
            return res                      # 根节点为空,则返回空数组
        from collections import deque
        queue = deque([root])
        while queue:
            q_list = []
            for _ in range(len(queue)):
                node = queue.popleft()
                q_list.append(node.val)
                # q_len -= 1
                if node.children:
                    queue.extend(node.children)
            res.append(q_list)
        return res

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

# 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 largestValues(self, root: Optional[TreeNode]) -> List[int]:
        queue = []
        res = []
        if not root:
            return res                          # 根节点为空,直接返回[]
        queue.append(root)                      # 根节点不为空,将根节点加入到队列queue中
        while queue: 
            q_len = len(queue)                  # 统计每层的节点数
            q_list = []                         # 存储每层的节点值
            while q_len > 0:                    # 每层剩余的节点数不为0
                node = queue.pop(0)             # 从队列中弹出第一个节点
                q_list.append(node.val)         # 将弹出节点的值,加入到q_list中
                q_len -= 1                      # 每弹出一个节点,这层剩余的节点数就减1
                # 弹出节点的左右子节点不为空,就将左右子节点添加到队列中
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            # 将每层节点值的最大值添加到res中
            res.append(max(q_list))
        return res

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

"""
# 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: 'Optional[Node]') -> 'Optional[Node]':
        queue = []
        if not root:
            return root                       # root为空,直接返回
        queue.append(root)
        while queue:
            q_len = len(queue)                # 记录每层节点的数量
            while q_len:
                node = queue.pop(0)           # 弹出节点
                if q_len == 1:                # 若本层剩余的节点为1
                    node.next = None          # 就将弹出的节点的next指向None
                else:                         # 若本层剩余的节点大于1
                    node.next = queue[0]      # 则将弹出的节点的next指向本层下一个弹出的节点
                q_len -= 1                    # 弹出一个元素,本层所剩节点数减1
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

        LeetCode117.填充每个节点的下一个右侧节点指针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':
        queue = []
        if not root:
            return root                       # root为空,直接返回
        queue.append(root)
        while queue:
            q_len = len(queue)                # 记录每层节点的数量
            while q_len:
                node = queue.pop(0)           # 弹出节点
                if q_len == 1:                # 若本层剩余的节点为1
                    node.next = None          # 就将弹出的节点的next指向None
                else:                         # 若本层剩余的节点大于1
                    node.next = queue[0]      # 则将弹出的节点的next指向本层下一个弹出的节点
                q_len -= 1                    # 弹出一个元素,本层所剩节点数减1
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

        LeetCode104.二叉树的最大深度

# 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 maxDepth(self, root: Optional[TreeNode]) -> int:
        queue = []
        s = 0
        if not root:
            return s                          # 根节点为空,直接返回0
        queue.append(root)                    # 根节点不为空,将根节点加入到队列queue中
        while queue:                          # 队列queue不为空
            q_len = len(queue)                # 统计每层的节点数
            s += 1                            # 层数自加1
            while q_len:                      # 每层剩余的节点数不为0
                node = queue.pop(0)           # 弹出节点
                q_len -= 1                    # 弹出节点后,剩余的节点数减1
                if node.left:                 # 弹出节点的左节点不为空,则加入队列
                    queue.append(node.left)
                if node.right:                # 弹出节点的右节点不为空,则加入队列
                    queue.append(node.right)
        return s                              # 当队列为空时,s就是二叉树的最大深度

        LeetCode111.二叉树的最小深度

# 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:
        queue = []
        s = 0
        if not root:
            return s
        queue.append(root)
        while queue:
            q_len = len(queue)                  # 统计每层的节点数
            s += 1                              # 统计深度
            while q_len:
                node = queue.pop(0)             # 每层剩余节点不为0时,弹出元素
                q_len -= 1                      # 弹出元素后,剩余节点数减1
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
                # 当节点的左右子节点均为空时,就是最小深度
                if node.left == None and node.right == None:
                    return s

二、LeetCode226.翻转二叉树 

        1:题目描述(226.翻转二叉树 )

        给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

        2:解题思路

        解法一:使用递归(递归视频讲解)

# 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]:
        # 递归法-前序遍历-中左右
        # 先处理中间节点,把中间节点的左右子节点进行交换
        # 再处理左子树
        # 最后处理右子树
        def invert(cur):
            if cur == None:
                return        # 当节点为空时,结束本层递归
            # 处理当前节点的左右子节点,将左右子节点进行交换
            cur.left, cur.right = cur.right, cur.left
            invert(cur.left)      # 再进行处理节点的左子树
            invert(cur.right)     # 处理节点的右子树
        invert(root)
        return root

         解法二:使用迭代法

# 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]:
        # 迭代法
        stack = []
        cur = root
        if not root:
            return root
        stack.append(root)         # 将根节点入栈
        while stack:
            node = stack.pop()     # 将栈中的最后一个节点弹出
            # 将节点的左右子节点进行交换
            node.left, node.right = node.right, node.left
            # 如果节点的左子节点不为空,将左节点入栈
            if node.left:
                stack.append(node.left)
            # 如果节点的右子节点不为空,将右节点入栈
            if node.right:
                stack.append(node.right)
        return root

        解法三:使用层序遍历

# 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]:
        # 层序遍历
        queue = []
        if not root:
            return root
        queue.append(root)         # 将跟节点入栈
        while queue:
            q_len = len(queue)         # 统计每层的节点数
            while q_len > 0:           # 每层剩余的节点数不为0时
                node = queue.pop(0)    # 弹出第一个节点
                # 将节点的左右子节点进行交换
                node.left, node.right = node.right, node.left
                q_len -= 1             # 弹出节点后,每层剩余的节点数减1
                # 弹出节点的左节点不为空,将左节点加入栈
                if node.left:
                    queue.append(node.left)
                # 弹出节点的右节点不为空,将右节点加入栈
                if node.right:
                    queue.append(node.right)
        return root

三、LeetCode101.对称二叉树 2 

        1:题目描述(101.对称二叉树 2 )

        给你一个二叉树的根节点 root , 检查它是否轴对称。

         2:解题思路

        使用递归解法(递归视频讲解)

# 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 isSymmetric(self, root: Optional[TreeNode]) -> bool:
        def symmetric(cur1, cur2):
            if cur1 == None and cur2 == None:
                return True             # 当cur1,cur2都为空
            if cur1 == None and cur2 != None:
                return False            # 当cur1为空,cur2不为空,说明不对称
            if cur1 != None and cur2 == None:
                return False            # 当cur1不为空,cur2为空,说明不对称
            if cur1.val != cur2.val:
                return False            # 当cur1,cur2对应的值不相等,说明不对称
            # 当cur1不为空,cur2不为空,cur1,cur2的值相等,则继续比较子节点
            # 需要比较cur1的左节点,和cur2的右节点,即对比外侧的节点是否对称
            outside = symmetric(cur1.left, cur2.right)
            # 比较cur1的右节点,和cur2的左节点,即对比内侧的节点是否对称
            inside = symmetric(cur1.right, cur2.left)
            # 获取内侧和外侧对比的结果,进行返回
            result = outside and inside
            return result
        # 当根节点不为空,左右节点都为空时,是对称的
        if root.left == None and root.right == None:
            return True
        # 当根节点为空或根节点的左节点或右节点为空时,说明不对称
        if not root or root.left == None or root.right == None:
            return False
        
        res = symmetric(root.left, root.right)
        return res

你可能感兴趣的:(算法训练营(LeetCode),算法,python,leetcode)