代码随想录算法训练营第14天|226.翻转二叉树、101. 对称二叉树、104. 二叉树的最大深度、111.二叉树的最小深度

打卡Day14

  • 1.226.翻转二叉树
  • 2.101. 对称二叉树
    • 扩展
      • 100. 相同的树
      • 572. 另一棵树的子树
  • 3.104. 二叉树的最大深度
    • 扩展
      • 559.n叉树的最大深度
  • 3.111.二叉树的最小深度

1.226.翻转二叉树

题目链接:226.翻转二叉树
文档讲解: 代码随想录

(1)递归法

思路:以二叉树的递归遍历为基础。确定递归函数的参数和返回值,输入树节点,输出根节点;确定终止条件,节点为空;确定逻辑,以前序遍历为例,先处理中节点,将其左右孩子对换,然后处理左节点,再处理右节点。

class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return None
        root.left, root.right = root.right,  root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root

后序遍历:

class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return None
        self.invertTree(root.left)
        self.invertTree(root.right)
        root.left, root.right = root.right, root.left
        return root

中序遍历:
这里会把某些节点的左右孩子翻转两次。遍历到左节点 A,将其左右孩子对调,然后返回根节点,翻转根节点的左右孩子后,再遍历的右节点还是 A,这样会导致 A 翻转两次。

class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return root
        self.invertTree(root.left)
        root.left, root.right = root.right,  root.left
        self.invertTree(root.left)
        return root

(2)迭代法

前序遍历:

class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return None
        stack = [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

后序遍历:

class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return None
        stack = [root]
        while stack:
            node = stack.pop()
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
            node.left, node.right = node.right, node.left
        return root

中序遍历:

class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return None
        stack = [root]
        while stack:
            node = stack.pop()
            if node.left:
                stack.append(node.left)
            node.left, node.right = node.right, node.left
            if node.left:
                stack.append(node.left)
        return root

(3)层序遍历

class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if not root:
            return None
        queue = collections.deque([root])
        while queue:
            size = len(queue)
            for i in range(size):
                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

2.101. 对称二叉树

题目链接:101. 对称二叉树
文档讲解: 代码随想录

思路:
比较是否是对称二叉树,不是比较左右节点是否一致,而是比较跟节点的左右子树,所以在递归遍历的过程中,要同时遍历两棵树。要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。所以要采用后序遍历,先把左右孩子进行比较,再处理中节点将结果返回根节点。

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):
        #首先排除空节点的情况
        if left == None and right != None: return False
        if left != None and right == None: return False
        if left == None and right == None: return True
        #再排除节点不空但值不同的情况
        if left.val != right.val: return False

        #此时,左右节点值一样,用递归做下一层判断
        outside = self.compare(left.left, right.right)
        inside = self.compare(left.right, right.left) 
        isSame = outside and inside
        return isSame       

迭代法:关键是将需要比较的节点相邻放入队列或者栈

(1)使用队列

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        queue = collections.deque()
        queue.append(root.left)
        queue.append(root.right)
        while queue:
            leftNode = queue.popleft()
            rightNode = queue.popleft()
            if not leftNode and not rightNode: 
                continue
            if not leftNode or not rightNode or leftNode.val != rightNode.val:
                return False
            queue.append(leftNode.left)
            queue.append(rightNode.right)
            queue.append(leftNode.right)
            queue.append(rightNode.left)
        return True

(2)使用栈

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        stack = []
        stack.append(root.left)
        stack.append(root.right)
        while stack:
            leftNode = stack.pop()
            rightNode = stack.pop()
            if not leftNode and not rightNode:
                continue
            if not leftNode or not rightNode or leftNode.val != rightNode.val:
                return False
            stack.append(leftNode.left)
            stack.append(rightNode.right)
            stack.append(leftNode.right)
            stack.append(rightNode.left)
        return True

层次遍历:

思路:比较每层的节点值是否对称

class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        if not root:
            return True
        queue = collections.deque([root.left, root.right])
        while queue:
            size = len(queue)
            if size % 2 != 0:
                return False
            level = []
            for i in range(size):
                node = queue.popleft()
                if node:
                    level.append(node.val)
                    queue.append(node.left)
                    queue.append(node.right)
                else:
                    level.append(None)
            if level != level[::-1]:
                return False
        return True

扩展

100. 相同的树

题目链接:100

class Solution(object):
    def isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """
        return self.compare(p,q)
    
    def compare(self, node1, node2):
        if not node1 and not node2:
            return True
        if not node1 or not node2 or node1.val != node2.val:
            return False
        
        leftside = self.compare(node1.left, node2.left)
        rightside = self.compare(node1.right, node2.right)
        isSame = leftside and rightside
        return isSame

572. 另一棵树的子树

题目链接:572

对于是否是否包含 subroot 的递归思路:确定输入为 root 和 subRoot;终止条件是 root 节点为空;比较逻辑是,首先确定compare(root, subRoot),如果不是则比较左右节点。

class Solution(object):
    def isSubtree(self, root, subRoot):
        """
        :type root: TreeNode
        :type subRoot: TreeNode
        :rtype: bool
        """

        #分两步:是否包含subroot;是否包含子树
        if not root:
            return False
        
        if self.compare(root, subRoot):
            return True
        
        return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)

    def compare(self, node1, node2):
        if not node1 and not node2:
            return True
        if not node1 or not node2 or node1.val != node2.val:
            return False
        leftside = self.compare(node1.left, node2.left)
        rightside = self.compare(node1.right, node2.right)
        isSame = leftside and rightside
        return isSame

3.104. 二叉树的最大深度

题目链接:104. 二叉树的最大深度
文档讲解: 代码随想录

这道题昨天用层序遍历的方式做过,今天主要掌握递归方法。前序遍历求的是深度,深度是指从根节点到该节点的最长简单路径边的条数或者节点数。后序遍历求的是高度,高度是指从该节点到叶子节点的最长简单路径边或者节点数。根节点的高度就是二叉树的最大深度。

(1)后序遍历
思路:确定递归函数输入输出,参数是树的根节点,返回值是 int 类型;确定终止条件,节点为空,则返回高度为0,因为是从1开始计数的;确定逻辑,先求左子树的高度,再求右子树的高度,最后取左右子树的最大高度再加一。

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        leftHeight = self.maxDepth(root.left)
        rightHeight = self.maxDepth(root.right)
        depth = 1 + max(leftHeight, rightHeight)
        return depth

(2)前序遍历

class Solution(object):
    def __init__(self):
        self.res = float('-inf')
    
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        self.getDepth(root, 1)
        return self.res

    def getDepth(self, node, depth):
        if not node:
            return
        self.res = max(self.res, depth)
        if node.left:
            self.getDepth(node.left, depth + 1)
        if node.right:
            self.getDepth(node.right, depth + 1)

(2)迭代法就是昨天学过的层序遍历。

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        queue = collections.deque([root])
        depth = 0
        while queue:
            depth += 1
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return depth

扩展

559.n叉树的最大深度

题目链接:559

递归:

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: Node
        :rtype: int
        """
        if not root:
            return 0
        max_depth = 1
        for child in root.children:
            max_depth = max(max_depth, self.maxDepth(child) + 1)
        return max_depth
        

迭代:

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: Node
        :rtype: int
        """
        if not root:
            return 0
        queue = collections.deque([root])
        depth = 0

        while queue:
            depth += 1
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                for child in node.children:
                    queue.append(child)
        return depth

使用栈:

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: Node
        :rtype: int
        """
        if not root:
            return 0
        maxx = 0
        stack = [(root, 1)]
        while stack:
            node, depth = stack.pop()
            maxx = max(maxx, depth)
            for child in node.children:
                stack.append((child, depth + 1))
        return maxx

3.111.二叉树的最小深度

题目链接:111.二叉树的最小深度
文档讲解: 代码随想录

求二叉树的最小深度和最大深度的差别主要在于处理左右孩子不为空的逻辑。不能处理为,左右子树的高度最小值加一。如图所示,当左子树为空时,该二叉树的最小深度应该是右子树最小深度再加一。

在这里插入图片描述
后序遍历:

class Solution(object):
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        if not root.left and root.right:
            return 1 + self.minDepth(root.right)
        if root.left and not root.right:
            return 1 + self.minDepth(root.left)
        return 1 + min(self.minDepth(root.left), self.minDepth(root.right))

前序遍历:

class Solution(object):
    def __init__(self):
        self.res = float('inf')
    
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        self.getMinDepth(root, 1)
        return self.res

    def getMinDepth(self, node, depth):
        if not node:
            return

        if not node.left and not node.right:
            self.res = min(self.res, depth)
        
        if node.left:
            self.getMinDepth(node.left, depth + 1)
        if node.right:
            self.getMinDepth(node.right, depth + 1)  

迭代法:

class Solution(object):
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        depth = 0
        queue = collections.deque([root])
        while queue:
            depth += 1
            size = len(queue)
            for i in range(size):
                node = queue.popleft()
                if not node.left and not node.right:
                    return depth
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return depth

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

博客的部署方法论

有了域名后,可以方便其他人记住并访问,历史上不乏大企业花大价钱购买域名的: 京东域名换成 JD.com,并且说是为了防止百度吸引流量,为什么?唯品会买下域名 VIP.COM 或花费千万 ‍ 域名提供商 如果想要域…

Xilinx FPGA:vivado关于真双端口的串口传输数据的实验

一、实验内容 用一个真双端RAM,端口A和端口B同时向RAM里写入数据0-99,A端口读出单数并存入单端口RAM1中,B端口读出双数并存入但端口RAM2中,当检测到按键1到来时将RAM1中的单数读出显示到PC端,当检测到按键2到来时&…

普通Java工程如何在代码中引用docker-compose.yml中的environment值

文章目录 一、概述二、常规做法1. 数据库配置分离2. 代码引用配置3. 编写启动类4. 支持打包成可执行包5. 支持可执行包打包成docker镜像6. docker运行 三、存在问题分析四、改进措施1. 包含environment 变量的编排文件2. 修改读取配置文件方式3. 为什么可以这样做 五、运行效果…

股票Level-2行情是什么,应该怎么使用,从哪里获取数据

行情接入方法 level2行情websocket接入方法-CSDN博客 相比传统的股票行情,Level-2行情为投资者打开了更广阔的视野,不仅限于买一卖一的表面数据,而是深入到市场的核心,提供了十档乃至千档的行情信息(沪市十档&#…

JavaWeb-【1】HTML

笔记系列持续更新,真正做到详细!!本次系列重点讲解后端,那么第一阶段先讲解前端 目录 1、Javaweb技术体系 2、BS架构说明 3、官方文档 4、网页组成 5、HTML 6、HTML快速入门 7、HTML基本结构 8、HTML标签 ​9、HTML标签使用细节 ①、font标签 ②、字符实体 ③、标…

图神经网络dgl和torch-geometric安装

文章目录 搭建环境dgl的安装torch-geometric安装 在跑论文代码过程中,许多小伙伴们可能会遇到一些和我一样的问题,就是文章所需要的一些库的版本比较老,而新版的环境跑代码会报错,这就需要我们手动的下载whl格式的文件来安装相应的…

SSM中小学生信息管理系统 -计算机毕业设计源码02677

摘要 随着社会的发展和教育的进步,中小学生信息管理系统成为学校管理的重要工具。本论文旨在基于SSM框架,采用Java编程语言和MySQL数据库,设计和开发一套高效、可靠的中小学生信息管理系统。中小学生信息管理系统以学生为中心,通过…

机器学习筑基篇,​Ubuntu 24.04 编译安装 Python 及多版本切换

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] Ubuntu 24.04 编译安装最新Python及多版本切换 描述:说到机器学习,人工智能,深度学习不免会提到Python这一门编程语言(人生苦短,及时Pyt…

【MySQL】逻辑架构与存储引擎

一、逻辑架构 1、MySQL逻辑架构 我们可以根据上图来对sql的执行过程进行分析 第一步:客户端与服务器建立一个连接,从连接池中分配一个线程处理SQL语句第二步:SQL接口接受SQL指令第三步:如果是5.7版本,就会先去缓存中…

Facebook数据仓库的变迁与启示

❃博主首页 &#xff1a; <码到三十五> ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a; <搬的每块砖&#xff0c;皆为峰峦之基&#xff1b;公众号搜索(码到…

史上最全的自抗扰控制(ADRC)学习资料

史上最全的自抗扰控制&#xff08;ADRC&#xff09;学习资料 需要的私信我~ 需要的私信我~ 需要的私信我~ ​ 本文将作者近些年来学习ADRC算法的学习资料进行汇总&#xff0c;整理了这一版相对较全的学习资料&#xff0c;包含参考文献以及仿真案例&#xff0c;适合初学者入门&…

STM32实现看门狗(HAL库)

文章目录 一. 看门狗1. 独立看门狗&#xff08;IWDG&#xff09;1.1 原理1.2 相关配置1.3 相关函数 2. 窗口看门狗&#xff08;WWDG&#xff09;2.1 原理2.2 相关配置2.3 相关函数 一. 看门狗 单片机在日常工作中常常会因为用户配置代码出现BUG&#xff0c;而导致芯片无法正常工…

21天学通C++:第九、十章节

第九章&#xff1a;类和对象 带默认值的构造函数参数 注意&#xff1a;默认构造函数是调用时可不提供参数的构造函数&#xff0c;而并不一定是不接受任何参数的构造函数。 因此&#xff0c;下面的构造函数虽然有两个参数&#xff0c;但它们都有默认值&#xff0c;因此也是默认…

CurrentHashMap巧妙利用位运算获取数组指定下标元素

先来了解一下数组对象在堆中的存储形式【数组长度&#xff0c;数组元素类型信息等】 【存放元素对象的空间】 Ma 基础信息实例数据内存填充Mark Word,ClassPointer,数组长度第一个元素第二个元素固定的填充内容 所以我们想要获取某个下标的元素首先要获取这个元素的起始位置…

Java 有什么必看的书?

Java必看经典书有这两本&#xff1a; 1、Java核心技术速学版&#xff08;第3版&#xff09; 经典Java开发基础书CoreJava速学版本&#xff01;Java入门优选书籍&#xff0c;更新至Java17&#xff0c;内容皆是精华&#xff0c;让Java学习更简单&#xff0c;让Java知识应用更快速…

fasttext工具介绍

fastText是由Facebook Research团队于2016年开源的一个词向量计算和文本分类工具。尽管在学术上并未带来巨大创新&#xff0c;但其在实际应用中的表现却非常出色&#xff0c;特别是在文本分类任务中&#xff0c;fastText往往能以浅层网络结构取得与深度网络相媲美的精度&#x…

STM32CubeMX实现4X5矩阵按键(HAL库实现)

为了实现计算器键盘&#xff0c;需要使用4X5矩阵按键&#xff0c;因此&#xff0c;我在4X4矩阵键盘上重新设计了一个4X5矩阵按键。原理图如下&#xff1a; 原理描述&#xff1a; 4X5矩阵按键&#xff0c;可以设置4个引脚为输出&#xff0c;5个引脚为输入模式&#xff0c;4个引…

MPS---MPQ86960芯片layout设计总结

MPQ86960 是一款内置功率 MOSFET 和栅极驱动的单片半桥。它可以在宽输入电压 (VIN) 范围内实现高达 50A 的连续输出电流 (IOUT)&#xff0c;通过集成MOSFET 和驱动可优化死区时间 (DT) 并降低寄生电感&#xff0c;从而实现高效率。 MPQ86960 兼容三态输出控制器&#xff0c;另…

Ubantu22.04 通过FlatPak安装微信

Ubuntu22.04 下使用Flatpak稳定安装微信&#xff01; 国际惯例&#xff0c;废话不多说&#xff0c;先上效果图。为啥使用Flatpak,因为Wechat官方只在FlatPak发布了最新的版本。之前使用了Wine以及Dock安装Wechat,效果都不是很理想&#xff0c;bug很多。所以使用了FlatPak。 Fl…