代码随想录27期|Python|Day15|二叉树|层序遍历|对称二叉树|翻转二叉树

news2024/9/20 20:25:07

本文图片来源:代码随想录

层序遍历(图论中的广度优先遍历)

这一部分有10道题,全部可以套用相同的层序遍历方法,但是需要在每一层进行处理或者修改。

102. 二叉树的层序遍历 - 力扣(LeetCode)

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

 队列长度法

# 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 []
        # 先把根节点放入队列
        queue = collections.deque([root])
        res = []
        # 然后逐层放入队列再弹出
        while queue:
            # 每层储存在level数组里
            level = []
            for _ in range(len(queue)):
                # 弹出根节点,存值
                cur = queue.popleft()
                level.append(cur.val)
                # 队列添加左右节点
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            # 每层走完
            res.append(level)
        return res

递归法

# 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]]
        """
        # 递归法
        levels = []
        self.helper(root, 0, levels)
        return levels

    def helper(self, node, level, levels):
        # 退出条件
        if not node:
            return
        # 当层数和levels的长度相等的时候,也就是满二叉树的时候,需要再加上一个新的层
        if len(levels) == level:
            levels.append([])
        levels[level].append(node.val)
        self.helper(node.left, level + 1, levels)
        self.helper(node.right, level + 1, levels)

107. 二叉树的层序遍历 II - 力扣(LeetCode)

只需要倒序输出即可,代码和上面102保持一致。

# 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 levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root:
            return []
        queue = collections.deque([root])
        res = []
        while queue:
            levels = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                levels.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            res.append(levels)
        # 反向输出即可
        return res[::-1]

199. 二叉树的右视图 - 力扣(LeetCode)

只需要每次把levels最后一个也就是最右侧的节点赋值给res即可。

# 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 rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        res = []
        queue = collections.deque([root])
        while queue:
            levels = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                levels.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            # 只需要每次把levels最后一个也就是左右侧的节点赋值给res即可
            res.append(levels[-1])
        return res

637. 二叉树的层平均值 - 力扣(LeetCode)

只需要在求出每层的基础上求平均即可。

注意作除法之前需要类型转换为float。

# 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 averageOfLevels(self, root):
        """
        :type root: TreeNode
        :rtype: List[float]
        """
        if not root:
            return []
        res = []
        queue = collections.deque([root])
        while queue:
            levels = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                levels.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            # 需要强制类型转换为浮点数
            sum_ = float(sum(levels))
            len_ = float(len(levels))
            avg = sum_ / len_
            res.append(avg)
        return res

429. N 叉树的层序遍历 - 力扣(LeetCode)

只需要把children列表里的元素按照顺序取出即可。

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

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: Node
        :rtype: List[List[int]]
        """
        if not root:
            return []
        res = []
        queue = collections.deque([root])
        while queue:
            levels = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                levels.append(cur.val)
                # children按列表储存child
                for child in cur.children:
                    queue.append(child)
            res.append(levels)
        return res

 515. 在每个树行中找最大值 - 力扣(LeetCode)

# 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 largestValues(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return []
        res = []
        queue = collections.deque([root])
        while queue:
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            # 每层最大值赋值给res
            res.append(max(level))
        return res

116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)

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

class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        if not root:
            return root  # 注意这一题的返回值是根节点地址,相当于只在原链表的基础上做修改
        queue = collections.deque([root])
        while queue:
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                # queue的下一个值其实就是next需要指向的地址
                # if _ < len(queue) - 1:
                #   cur.next = queue[0]
                level.append(cur)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            # 在每一层遍历
            for i in range(len(level) - 1):
                level[i].next = level[i + 1]
        return root

 117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)

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

class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        if not root:
            return root  # 注意这一题的返回值是根节点地址,相当于只在原链表的基础上做修改
        queue = collections.deque([root])
        while queue:
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                # queue的下一个值其实就是next需要指向的地址
                # if _ < len(queue) - 1:
                #   cur.next = queue[0]
                level.append(cur)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            # 在每一层遍历
            for i in range(len(level) - 1):
                level[i].next = level[i + 1]
        return root    

104. 二叉树的最大深度 - 力扣(LeetCode)

# 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 maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 广度优先
        if not root:
            return 0
        cnt = 0
        queue = collections.deque([root])
        while queue:
            # 构造一层的队列
            for _ in range(len(queue)):
                cur = queue.popleft()
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            # 构造完加一
            cnt += 1
        return cnt

        # 递归法
        if not root:
            return 0
        else:
            left_height = self.maxDepth(root.left)
            right_height = self.maxDepth(root.right)
        return max(left_height, right_height) + 1

        # 精简递归
        return 0 if not root else max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

111. 二叉树的最小深度 - 力扣(LeetCode)

找到第一个叶子节点就退出while。这里用到了flag标记。

# 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 minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 广度优先
        if not root:
            return 0
        cnt = 0
        queue = collections.deque([root])
        flag = 0
        while queue:
            # 构造一层的队列
            for _ in range(len(queue)):
                cur = queue.popleft()
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
                if not (cur.left or cur.right):
                    flag = 1
            cnt += 1
            # 构造完加一
            if flag:
                break
        return cnt

226. 翻转二叉树 - 力扣(LeetCode)

深度遍历

omg!baseline只需要上面的套模板即可实现!!这不神奇吗??!!

根据顺序做具体的微调

前序/后续

只需要在原来代码的基础上加上子节点的交换过程即可。

递归法里的写法:

root.left, root.right = root.right, root.left

 迭代法里的写法:

node = stack.pop()   
node.left, node.right = node.right, node.left

中序

需要注意中序在执行完交换之后原来的左节点是右节点,但是right指针指向的是原left节点,所以需要在两次递归的时候都要指向left

self.invertTree(root.left)
root.left, root.right = root.right, root.left
selfinvertTree(root.left)

广度遍历(层序遍历)

# 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 invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        # 层序遍历
        if not root:
            return root
        queue = collections.deque([root])
        while queue:
            for _ in range(len(queue)):
                node = queue.popleft()
                # 对于取出队列里的每一个节点交换左右子节点
                node.left, node.right = node.right, node.left
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

101. 对称二叉树 - 力扣(LeetCode)

递归

 思路是分别比较两个子树的内侧和外侧,然后将结果取交集返回中间节点。所以确定便利的顺序一定是后序遍历(最后一个确定中间节点)。

因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。

# 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 isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
    # 递归法
        if not root:
            return True
        return self.compare(root.left, root.right)
    def compare(self, left, right):
        """
        左----右----result
        空    空     True
        空    有     False
        有    空     False
        有 != 有     False
        有 == 有     True
        """
        if left == None and right == None:
            return True
        elif left == None and right != None:
            return False
        elif left != None and right == None:
            return False
        elif left.val != right.val:
            return False
        else:  # 此时已经说明left == right,需要再判断他们的子节点
            outside = self.compare(left.left, right.right)  # 外侧子节点
            inside = self.compare(left.right, right.left)  # 内侧子节点
        is_same = outside and inside  # 求交集
        return is_same

 层序遍历

# 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 isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # 层次法
        queue = collections.deque([root])
        while queue:
            level_val = []  # 只需要保存值
            for _ in range(len(queue)):
                node = queue.popleft()
                if node:
                    level_val.append(node.val)
                    queue.append(node.left)
                    queue.append(node.right)
                else:  # 空节点赋值为None
                    level_val.append(None)
            if level_val != level_val[::-1]:  # 倒序比较数组
                return False
        return True

队列或栈

关键:成对取出外侧和内侧节点进行比较。

# 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 isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # 栈或队列(队列只要把栈改成队列,pop搞成popleft就可以了)
        if not root:
            return True
        stack = []
        stack.append(root.left)
        stack.append(root.right)
        while stack:
            left = stack.pop()
            right = stack.pop()
            if left == None and right == None:
                continue  # 注意在while里需要continue
            if left == None or right == None or left.val != right.val:
                return False
            stack.append(left.left)
            stack.append(right.right)
            stack.append(left.right)
            stack.append(right.left)
        return True

2个相关题

100. 相同的树 - 力扣(LeetCode)

两个树,如果采用层序遍历的方法最好把重复部分封装成一个整体的函数。

# 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 isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """
        # 层次法
        queue1 = collections.deque([p])
        queue2 = collections.deque([q])
        while queue1 and queue2:
            if len(queue1) != len(queue2):
                return False
            level1 = self.get_level(queue1)
            level2 = self.get_level(queue2)
            if level1 != level2:
                return False
        return True

    def get_level(self, queue):
        level_val = []
        for _ in range(len(queue)):
            node = queue.popleft()
            if node:
                level_val.append(node.val)
                queue.append(node.left)
                queue.append(node.right)
            else:
                level_val.append(None)
        return level_val

 572. 另一棵树的子树 - 力扣(LeetCode)

# 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 isSubtree(self, root, subRoot):
        """
        :type root: TreeNode
        :type subRoot: TreeNode
        :rtype: bool
        """
        # 深度遍历+递归
        if not root:
            return False
        
        return self.check_is_same(root, subRoot) or self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)

    def check_is_same(self, root, subroot):
        if root == None and subroot == None:
            return True
        elif root == None or subroot == None or root.val != subroot.val:
            return False
        return self.check_is_same(root.left, subroot.left) and self.check_is_same(root.right, subroot.right)

第15天完结🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1312248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

root登录提示:Access denied

一、问题&#xff1a; 在使用xshell工具用root账号登录服务器时提示Access denied&#xff0c;拒绝访问&#xff0c;SSH服务器拒绝了密码&#xff0c;但用其它用户又可以连接. 二、原因 是因为sshd的设置不允许root用户用密码远程登录的问题 三、解决办法 使用可以登录的账…

Parade Series - Message Interaction

if (true) {Swal.fire("节目发布", "发布完毕", "success");event.preventDefault(); } if (false) {Swal.fire("节目发布", "发布失败", "error");event.preventDefault(); }if (true) {for (var i 0; i < b…

Matlab论文插图绘制模板第130期—函数曲面图

在之前的文章中&#xff0c;分享了Matlab函数折线图的绘制模板&#xff1a; 函数三维折线图&#xff1a; 函数网格曲面图&#xff1a; 进一步&#xff0c;再来分享一下函数曲面图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&a…

DBCA创建RAC的过程截图

以下错误是由于配置的内存较大&#xff0c;而大页&#xff08;HugePage&#xff09;配置较小导致&#xff0c;调整大页后就好了。

Luminar Neo:超强AI图像编辑器,助力你轻松创作完美照片!

如果你是一位热爱摄影和图像编辑的人&#xff0c;那么我相信你一定会喜欢 Luminar Neo&#xff08;超强AI图像编辑器&#xff09;&#xff01;不仅仅是一款普通的图像编辑软件&#xff0c;Luminar Neo融合了人工智能技术&#xff0c;让你在编辑照片时拥有更多可能性和创意。 L…

Python小程序 - 表格数值统计

题设&#xff1a;Excel表格中&#xff0c;计算如下图所示不同颜色&#xff08;蓝、黄、桔&#xff09;单元格值&#xff1a;各颜色填涂的单元格值的总和条件&#xff1a; - Excle表格中 - 分色标记&#xff0c;单元格有值 - 开始列&#xff08;当前为D&#xff09;&#xff0c;…

基于SSM的咖啡销售系统vue论文

摘 要 现代社会是计算机技术普遍发展与应用的社会&#xff0c;甚至无网不成行&#xff0c;由此可见信息网络已经在商家活动或者人们生活中占据非常重要的地位&#xff0c;成为各行业不可割舍的重要组成。而随着网络地位的越来越突出&#xff0c;网络平台已经超越电视、报纸等传…

记一次clickhouse启动报错

clickhouse一次排错 clickhouse启动报错 报错&#xff1a; Application: Code: 210. DB::Exception: Listen [::]:8123 failed: Poco::Exception. Code: 1000, e.code() 0, DNS error: EAI: Address family for hostname not supported (version 23.3.1.2823 (official bui…

新零售ERP软件功能有哪些?新零售ERP系统哪个操作简单

新零售企业通常存在多仓库、多营销渠道、多业务模式、价格策略灵活、供应链复杂等情况&#xff0c;如何实现配送、财务、客户、订单、仓储等业务数据一体化和智能化管理&#xff0c;是不少新零售企业需要解决的难点。 随着新零售企业数量不断增多&#xff0c;行业之间的竞争也…

【Python必做100题】之第十四题(反向输出四位数)

题目&#xff1a;编写程序&#xff1a;输入一个四位整数&#xff0c;反向输出对应的四位数 思路&#xff1a;将整数转化为字符串类型&#xff0c;利用字符串的切片进行逆转输出 代码如下&#xff1a; #编写程序&#xff1a;输入一个四位整数&#xff0c;反向输出对应的四位数…

小间距LED显示屏在会议室的应用

LED显示屏作为自发光显示设备&#xff0c;在其高亮度、远观距离、高对比度和清晰度等特点的推动下&#xff0c;已经成为不可或缺的显示设备之一。随着LED显示屏厂家和整个产业链对产品的不断完善&#xff0c;小间距LED显示屏正逐渐成为会议室中的首选。那么&#xff0c;什么是细…

【深度学习】强化学习(三)强化学习的目标函数

文章目录 一、强化学习问题1、交互的对象2、强化学习的基本要素3、策略&#xff08;Policy&#xff09;4、马尔可夫决策过程5、强化学习的目标函数1. 总回报&#xff08;Return&#xff09;2. 折扣回报&#xff08;Discounted Return&#xff09;a. 折扣率b. 折扣回报的定义 3.…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于乐观行动-评判深度强化学习的含氢综合能源系统低碳经济调度》

这个标题涉及到基于乐观行动的深度强化学习在含氢综合能源系统低碳经济调度方面的评判。让我们逐步解读&#xff1a; 基于乐观行动&#xff08;Optimistic Action&#xff09;&#xff1a; 可能指的是在决策或行动中采取积极、乐观的策略&#xff0c;即在不确定性环境下&#x…

高效排队,紧急响应:RabbitMQ Priority Queue全面指南【RabbitMQ 九】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 高效排队&#xff0c;紧急响应&#xff1a;RabbitMQ Priority Queue全面指南 引言前言第一&#xff1a;初识RabbitMQ Priority Queue插件插件的背景和目的&#xff1a;为什么需要消息优先级&#xff1…

C++ 指针基础

指针的定义 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h>int main() {int a 10;printf("%p\n", &a); // &a 表示取&#xff08;a&#xff09;的地址 000000842FD9FB64// 存放指针&#xff08;地址&#xff09;的变量就是指针变量&#xff0c…

系统运行占用过高

1、CPU过高的问题排查 示例代码&#xff1a; public class Test { static class MyThread extends Thread { public void run() { // 死循环&#xff0c;消耗CPU int i 0; while (true) { i; } } } public static void main(String args[]) throws InterruptedException { ne…

DevOps搭建(十二)-阿里云镜像仓库的使用详解

有时候,不想在服务器自己搭建镜像仓库,那么我们可以使用阿里云镜像仓库,详细使用方法如下。 1、容器镜像服务 阿里云镜像服务地址: https://cr.console.aliyun.com/cn-hangzhou/instances 选择个人实例 2、创建命名空间 3、创建镜像仓库 考虑到安全性,仓库类型选择我…

【贝叶斯分析】计算机科学专业博士作业二

1 第一题 1.1 题目 已知变量A和B的取值只能为0或1&#xff0c;A⫫&#x1d469;&#xff0c;且&#x1d45d;(&#x1d434;1)0.65&#xff0c;&#x1d45d;(&#x1d435;1)0.77。C的取值与A和B有关&#xff0c;具体关系如下图所表&#xff1a; ABP(C1|A,B)000.1010.99100…

使用Pytorch从零开始构建StyleGAN2

这篇博文是关于 StyleGAN2 的&#xff0c;来自论文Analyzing and Improving the Image Quality of StyleGAN&#xff0c;我们将使用 PyTorch 对其进行干净、简单且可读的实现&#xff0c;并尝试尽可能地还原原始论文。 如果您没有阅读 StyleGAN2 论文。或者不知道它是如何工作…

mysql 5.7.34升级到5.7.44修补漏洞

mysql 5.7.34旧版本&#xff0c;漏扫有漏洞&#xff0c;升级到最新版本 旧版本5.7.34在 /home/mysql/mysql中安装 备份旧版本数据还有目录 数据库备份升级 tar -xf mysql-5.7.44-el7-x86_64.tar #覆盖旧版本数据库文件 #注意看看文件是否和你起服务的用户一样 \cp -r mysql-5…