Python题解Leetcode Hot100之二叉树

1. 二叉树的中序遍历

  • 题目描述
    给定一个二叉树,返回它的中序遍历。
  • 解题思路
    使用递归的方法对左子树进行中序遍历,然后访问根节点,最后对右子树进行中序遍历。也可以使用栈来模拟递归的过程,迭代地进行中序遍历。
  • 代码
    class Solution:def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:path = []def dfs(node):nonlocal pathif not node:return dfs(node.left)path.append(node.val)dfs(node.right)dfs(root)return path
    

2. 二叉树的最大深度

  • 题目描述
    给定一个二叉树,找出其最大深度。最大深度是从根节点到最远叶子节点的最长路径上的节点数。
  • 解题思路
    使用递归方法计算左右子树的最大深度,然后取最大值加一。也可以使用广度优先搜索(BFS)遍历树的每一层,记录层数。
  • 代码
    class Solution:def maxDepth(self, root: Optional[TreeNode]) -> int:if not root:return 0left = self.maxDepth(root.left)right = self.maxDepth(root.right)return max(left, right) + 1
    

3. 翻转二叉树

  • 题目描述
    镜像翻转一棵二叉树。
    在这里插入图片描述

  • 解题思路
    可以看到翻转二叉树就是对所有节点的左右节点进行翻转,因此使用递归方法交换每个节点的左右子节点。

  • 代码

    class Solution:def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:if not root:return Noneinvert_left = self.invertTree(root.left)invert_right = self.invertTree(root.right)root.left, root.right = invert_right, invert_leftreturn root
    

4. 对称二叉树

  • 题目描述
    给定一个二叉树,检查它是否是镜像对称的。
    在这里插入图片描述

  • 解题思路
    观察发现二叉树对称就是,比较左节点的左节点和右节点的右节点是否相同,左节点的右节点和右节点的左节点是否相同。此题特殊在需要写一个辅助函数,输入是两个节点,并从root.left和root.right开始递归

  • 代码

    class Solution:def isSymmetric(self, root: Optional[TreeNode]) -> bool:def symmetric(left, right):if not left and not right:return Trueif not left or not right:return Falseif left.val != right.val:return Falsereturn symmetric(left.left, right.right) and symmetric(left.right, right.left)return symmetric(root.left, root.right)
    

5. 二叉树的直径

  • 题目描述
    给定一棵二叉树,计算它的直径。二叉树的直径是树中任意两个节点路径长度中的最大值。
  • 解题思路
    使用递归方法计算每个节点的左右子树深度,然后更新最大直径。每个节点的直径是左右子树深度之和,注意直径的定义是边的数量而不是节点数。
  • 代码
    class Solution:def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:res = 0def max_height(root):nonlocal resif not root:return 0left = max_height(root.left)right = max_height(root.right)res = max(res, left + right)return max(left, right) + 1max_height(root)return res
    

6. 二叉树的层序遍历

  • 题目描述
    给定一个二叉树,返回其按层次遍历的节点值。即逐层地,从左到右访问所有节点。
  • 解题思路
    使用队列进行广度优先搜索(BFS),逐层访问每个节点,并将节点值存入结果列表。注意在将读取的每个节点的左右节点压入队列的时候,要记得判断左右节点是不是None;
  • 代码
    class Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:if not root:return []que = deque()que.append(root)res = []while len(que) != 0:cur_level = []n = len(que)for i in range(n):node = que.popleft()cur_level.append(node.val)# 注意要判断节点是不是None,避免将None加入到queif node.left:que.append(node.left)if node.right:que.append(node.right)res.append(cur_level)return res
    

7. 将有序数组转换为二叉搜索树

  • 题目描述
    将一个按照升序排序的有序数组转换为一棵高度平衡的二叉搜索树。
  • 解题思路
    使用递归方法,每次选择中间元素作为根节点,左右子数组分别作为左右子树,递归构造二叉搜索树。
  • 代码
    class Solution:def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:n = len(nums)if n == 0:return Noneif n == 1:return TreeNode(val = nums[0])mid = n // 2node = TreeNode(val = nums[mid])node.left = self.sortedArrayToBST(nums[: mid])node.right = self.sortedArrayToBST(nums[mid+1: ])return node
    

8. 验证二叉搜索树

  • 题目描述
    给定一个二叉树,判断其是否是一个有效的二叉搜索树(BST)。
  • 解题思路
    ==二叉搜索树的性质:中序遍历是有序的。==因此对二叉搜索树进行中序遍历,利用一个全局变量来记录上一节点的值,这样遍历所有节点并检查节点值是否严格递增。
  • 代码
    class Solution:def isValidBST(self, root: Optional[TreeNode]) -> bool:# 设置全局变量,用于记录上一个节点的值last_val = float("-inf")# 中序遍历def inorder(root):nonlocal last_valif not root:return True# 查验左子树是不是二叉搜索树left = inorder(root.left)# 查验当前节点if root.val <= last_val:return Falselast_val = root.val# 查验右子树right = inorder(root.right)return left and rightreturn inorder(root)
    

9. 二叉搜索树中第K小的元素

  • 题目描述
    给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
  • 解题思路
    依然是利用二叉搜索树的性质,使用中序遍历二叉搜索树,计数遍历到第 k 个节点时,即为第 k 小的元素。
  • 代码
class Solution:def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:def dfs(root):if not root: returndfs(root.left)if self.k == 0: returnself.k -= 1if self.k == 0: self.res = root.valdfs(root.right)self.k = kdfs(root)return self.res

10. 二叉树的右视图

  • 题目描述
    给定一棵二叉树,想象自己站在它的右侧,按从顶部到底部的顺序,返回看到的节点值。
  • 解题思路
    使用广度优先搜索(BFS),逐层记录最后一个节点的值。
  • 代码
    class Solution:def rightSideView(self, root: Optional[TreeNode]) -> List[int]:if not root:return []que = deque()que.append(root)res = []while len(que) != 0:n = len(que)for i in range(n):node = que.popleft()if i == n - 1:res.append(node.val)if node.left:que.append(node.left)if node.right:que.append(node.right)return res
    

11. 二叉树展开为链表

  • 题目描述
    给定一个二叉树,原地将它展开为一个单链表,链表的顺序和先序遍历相同。
    在这里插入图片描述

  • 解题思路
    对二叉树进行先序遍历,然后把遍历到的节点依次连接起来,使用一个全局变量记录上一个节点;

  • 代码

    class Solution:def flatten(self, root: Optional[TreeNode]) -> None:"""Do not return anything, modify root in-place instead."""if not root:returndummy_root = TreeNode()prev = dummy_rootdef dfs(node):nonlocal previf not node:return # 这里要先吧left和right保存下来left = node.leftright = node.rightprev.right = nodeprev.left = Noneprev = nodedfs(left)dfs(right)dfs(root)
    

12. 从前序与中序遍历序列构造二叉树

  • 题目描述
    根据一棵树的前序遍历与中序遍历构造二叉树。
  • 解题思路
    使用递归方法,前序遍历的第一个元素为根节点,根据根节点的值找到中序遍历中根节点的位置,然后就能根据中序遍历分割左右子树的节点,将两个遍历分成左右两部分,递归构造二叉树。
  • 代码
class Solution:def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:if len(preorder) == 0:return Noneif len(preorder) == 1:return TreeNode(val=preorder[0])root_val = preorder[0]# 在中序遍历中从下标为0开始寻找i = 0while inorder[i] != root_val:i += 1root = TreeNode(root_val)root.left = self.buildTree(preorder[1:i+1], inorder[:i])root.right = self.buildTree(preorder[i+1:], inorder[i+1:])return root

13. 路径总和 III

  • 题目描述
    给定一个二叉树,它的每个节点都存放一个整数值。找出路径和等于给定数值的路径总数。路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
    在这里插入图片描述

  • 解题思路
    使用双重递归,外层递归遍历每个节点,内层递归计算以当前节点为起点的路径数。

  • 代码

    class Solution:def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:res = 0# 计算以当前节点为起点的路径数def backtrace(node, s, targetSum):nonlocal resif not node:return s += node.valif s == targetSum:res += 1backtrace(node.left, s, targetSum)backtrace(node.right, s, targetSum)s -= node.val# 递归遍历每个节点def dfs(root, targetSum):if not root:return backtrace(root, 0, targetSum)dfs(root.left, targetSum)dfs(root.right, targetSum)dfs(root, targetSum)return res
    

14. 二叉树的最近公共祖先

  • 题目描述
    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
  • 解题思路
    使用递归方法,如果当前节点为目标节点之一或为空,则返回当前节点;否则,递归查找左右子树的最近公共祖先。如果左右子树都找到目标节点,则当前节点为最近公共祖先。
  • 代码
    class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if not root:return rootif root == p or root == q:return rootleft = self.lowestCommonAncestor(root.left, p, q)right = self.lowestCommonAncestor(root.right, p, q)if left and right:return rootif left:return leftif right:return rightreturn None
    

15. 二叉树中的最大路径和

  • 题目描述
    给定一个非空二叉树,返回其最大路径和。路径被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

  • 解题思路
    经过某个节点cur的最大路径和 = cur.val + max(cur.left起始的路径最大和, 0) + max(cur.right起始的路径最大和,0)。使用双层递归,内层递归求以当前节点为起始节点的路径最大和,外层递归遍历所有节点,根据上面的公式求取最终结果;

  • 代码

    class Solution:def maxPathSum(self, root: Optional[TreeNode]) -> int:# 求以当前节点为起始节点的路径最大和def backtrace(root):if not root:return 0left = backtrace(root.left)right = backtrace(root.right)if left <= 0 and right <= 0:return root.valreturn root.val + max(left, right)# 外层递归遍历所有节点,根据上面的公式求取最终结果def dfs(root):nonlocal resif not root:returnleft = backtrace(root.left)right = backtrace(root.right)cur = root.valif left > 0:cur += leftif right > 0:cur += rightres = max(cur, res)dfs(root.left)dfs(root.right)res = float("-inf")dfs(root)return res  
    

16. 总结

  • 递归分解成子问题
    这一类问题可以递归将一个二叉树分解成左右子树,分别进行相同的问题求解,依次类推;这类问题包括二叉树的最大深度、翻转二叉树、对称二叉树
  • 二叉搜索树
    重要性是中序遍历是升序的
  • 层序遍历
    队列

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leica Cyclone 3DR2024 一款功能强大的点云建模软件下载License获取

Leica Cyclone 3DR 2024 是一款功能强大的点云建模软件&#xff0c;使用旨在为用户提供全面的点云管理、自动化的点云分析&#xff0c;结合强大的建模&#xff0c;在一个直观友好的环境中&#xff0c;专注的完成挑战&#xff0c;提高生产力&#xff0c;轻松创建并交付专业的成果…

c++:struct和class的区别

C和C中struct的区别 (1)C中不支持成员函数&#xff08;只能通过函数指针成员变量间接支持&#xff09;&#xff0c;而C源生支持。 (2)C中不支持static成员&#xff0c;而C中支持。后面会详细讲&#xff0c;C static class是一个大知识点 (3)访问权限&#xff0c;C中默认public…

HTML5使用<mark>标签:高亮显示文本

1、<mark>标签的使用 mark 标签用于表示页面中需要突出显示或高亮的一段文本&#xff0c;这段文本对于当前用户具有参考作用。它通常在引用原文以引起读者注意时使用。<mark>标签的作用相当于使用一支荧光笔在打印的纸张上标出一些文字。它与强调不同&#xff0c;…

聊天广场(Vue+WebSocket+SpringBoot)

由于心血来潮想要做个聊天室项目 &#xff0c;但是仔细找了一下相关教程&#xff0c;却发现这么多的WebSocket教程里面&#xff0c;很多都没有介绍详细&#xff0c;代码都有所残缺&#xff0c;所以这次带来一个比较完整得使用WebSocket的项目。 目录 一、效果展示 二、准备工…

手写实现一个ORM框架

手写实现一个ORM框架 什么是ORM框架、ORM框架的作用效果演示框架设计代码细节SqlBuilderSqlExecutorStatementHandlerParameterHandlerResultSetHandler逆序生成实体类 大家好&#xff0c;本人最近写了一个ORM框架&#xff0c;想在这里分享给大家&#xff0c;让大家来学习学习。…

C++ 多态篇

文章目录 1. 多态的概念和实现1.1 概念1.2 实现1.2.1 协变1.2.2 析构函数1.2.3 子类虚函数不加virtual 2. C11 final和override3.1 final3.2 override 3. 函数重载、重写与隐藏4. 多态的原理5. 抽象类6.单继承和多继承的虚表6.1 单继承6.2 多继承 7. 菱形继承的虚表(了解)7.1 菱…

I/O多路复用

参考面试官&#xff1a;简单说一下阻塞IO、非阻塞IO、IO复用的区别 &#xff1f;_unix环境编程 阻塞io和非阻塞io-CSDN博客 同步阻塞(BIO) BIO 以流的方式处理数据 应用程序发起一个系统调用&#xff08;recvform&#xff09;&#xff0c;这个时候应用程序会一直阻塞下去&am…

Interview preparation--Https 工作流程

HTTP 传输的弊端 如上图&#xff0c;Http进行数据传输的时候是明文传输&#xff0c;导致任何人都有可能截获信息&#xff0c;篡改信息如果此时黑客冒充服务器&#xff0c;或者黑客窃取信息&#xff0c;则其可以返回任意信息给客户端&#xff0c;而且不被客户端察觉&#xff0c;…

2、图形验证码

1、图形验证码设计 1.1思路 现今&#xff0c;市面上的图形验证码付费的&#xff0c;免费的多种多样&#xff0c;主要形式有滑动拼图、文字点选、语序点选、字体识别、空间推理、智能随机等。 而处理也分为web端和sever端两部分 此处以免费的kaptcha 为例&#xff0c;进行数字图…

认识流式处理框架Apache Flink

目录 一、Apache Flink 的基础概念 1.1 Apache Flink是什么&#xff1f; 1.2 Flink的定义 二、Apache Flink 的发展史 2.1 Flink前身Stratosphere 2.2 Flink发展时间线及重大变更 三、Flink核心特性 3.1 批流一体化 3.2 同时支持高吞吐、低延迟、高性能 3.3 支持事件时…

全新UI自助图文打印系统小程序源码 PHP后端 附教程

最新自助图文打印系统和证件照云打印小程序源码PHP后端&#xff0c;为用户用户自助打印的服务&#xff0c;包括但不限于文档、图片、表格等多种格式的文件。此外&#xff0c;它们还提供了诸如美颜、换装、文档打印等功能&#xff0c;以及后台管理系统&#xff0c;方便管理员对打…

小(微)间距P1.538COB渠道现货销售将加速全面升级替换SMD产品。

COB&#xff08;Chip on Board&#xff09;技术&#xff0c;如一颗璀璨的星辰&#xff0c;在上世纪60年代的科技夜空中悄然升起。它巧妙地将LED芯片镶嵌在PCB电路板的怀抱中&#xff0c;再用特种树脂为其披上一层坚韧的外衣&#xff0c;宛如一位精心雕琢的艺术家在创作一幅完美…

实战whisper第三天:fast whisper 语音识别服务器部署,可远程访问,可商业化部署(全部代码和详细部署步骤)

Fast Whisper 是对 OpenAI 的 Whisper 模型的一个优化版本,它旨在提高音频转录和语音识别任务的速度和效率。Whisper 是一种强大的多语言和多任务语音模型,可以用于语音识别、语音翻译和语音分类等任务。 Fast Whisper 的原理 Fast Whisper 是在原始 Whisper 模型的基础上进…

从0到1:培训老师预约小程序开发笔记二

背景调研 培训老师预约小程序&#xff1a; 教师和学生可以更便捷地安排课程&#xff0c;并提升教学质量和学习效果&#xff0c;使之成为管理和提升教学效果的强大工具。培训老师可以在小程序上设置自己的可预约时间&#xff0c;学员可以根据老师的日程安排选择合适的时间进行预…

Studying-代码随想录训练营day27| 贪心算法理论基础、455.分发饼干、376.摆动序列、53.最大子序和

第27天&#xff0c;贪心开始&#xff01;(ง •_•)ง&#x1f4aa;&#xff0c;编程语言&#xff1a;C 目录 贪心算法理论基础 贪心的套路 贪心的一般解题步骤 总结 455.分发饼干 376.摆动序列 53.最大子序和 总结 贪心算法理论基础 什么是贪心&#xff1f;—— 贪…

计算机组成原理学习笔记(一)

计算机组成原理 [类型:: [[计算机基础课程]] ] [来源:: [[B站]] ] [主讲人:: [[咸鱼学长]] ] [评价:: ] [知识点:: [[系统软件]] & [[应用软件]] ] [简单解释:: 管理计算机系统的软件&#xff1b; 按照任务需要编写的程序 ] [问题:: ] [知识点:: [[机器字长]] ] [简单…

三相感应电机的建模仿真(2)基于ABC相坐标系S-Fun的仿真模型

1. 概述 2. 三相感应电动机状态方程式 3. 基于S-Function的仿真模型建立 4. 瞬态分析实例 5. 总结 6. 参考文献 1. 概述 前面建立的三相感应电机在ABC相坐标系下的数学模型是一组周期性变系数微分方程&#xff08;其电感矩阵是转子位置角的函数&#xff0c;转子位置角随时…

ubuntu22 sshd设置

专栏总目录 一、安装sshd服务 sudo apt updatesudo apt install -y openssh-server 二、配置sshd 使用文本编辑器打开/etc/ssh/sshd_config sudo vi /etc/ssh/sshd_config &#xff08;一&#xff09;配置sshd服务的侦听端口 建议将ssh的侦听端口改为7000以上的端口&#…

安装 tesseract

安装 tesseract 1. Ubuntu-24.04 安装 tesseract2. Ubuntu-24.04 安装支持语言3. Windows 安装 tesseract4. Oracle Linux 8 安装 tesseract 1. Ubuntu-24.04 安装 tesseract sudo apt install tesseract-ocr sudo apt install libtesseract-devreference: https://tesseract-…

Android- Framework 非Root权限实现修改hosts

一、背景 修改system/etc/hosts&#xff0c;需要具备root权限&#xff0c;而且remount后&#xff0c;才能修改&#xff0c;本文介绍非root状态下修改system/etc/hosts方案。 环境&#xff1a;高通 Android 13 二、方案 非root&#xff0c;system/etc/hosts只有只读权限&…