LeetCode Hot100 刷题笔记(4)—— 二叉树、图论

news2025/4/3 3:29:30

目录

一、二叉树

1. 二叉树的深度遍历(DFS:前序、中序、后序遍历)

2. 二叉树的最大深度

3. 翻转二叉树

4. 对称二叉树

5. 二叉树的直径

6. 二叉树的层序遍历

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

8. 验证二叉搜索树

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

10. 二叉树的右视图

11. 二叉树展开为链表

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

13. 路径总和 III

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

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

二、图论

1. 岛屿数量

2. 腐烂的橘子

3. 课程表

4. 实现 Trie (前缀树)


前言

一、二叉树:二叉树的中序遍历,二叉树的最大深度,翻转二叉树,对称二叉树,二叉树的直径,二叉树的层序遍历,将有序数组转换为二叉搜索树,验证二叉搜索树,二叉搜索树中第 K 小的元素,二叉树的右视图,二叉树展开为链表,从前序与中序遍历序列构造二叉树,路径总和 III,二叉树的最近公共祖先,二叉树中的最大路径和。

二、图论:岛屿数量,腐烂的橘子,课程表,实现 Trie (前缀树)。


一、二叉树

1. 二叉树的深度遍历(DFS:前序、中序、后序遍历)

 原题链接:94. 二叉树的中序遍历 - 力扣(LeetCode)

# (1)前序遍历:根-左-右
class Solution(object):
    def preorderTraversal(self, root):
        res = []
        def preorder(root):
            if not root:
                return 
            res.append(root.val)
            preorder(root.left)
            preorder(root.right)
        preorder(root)
        return res
# (2)中序遍历:左-根-右
class Solution(object):
    def inorderTraversal(self, root):
        res = []
        def inorder(root):
            if not root:
                return 
            inorder(root.left)
            res.append(root.val)
            inorder(root.right)
        inorder(root)
        return res

# (3)后序遍历:左-右-根
class Solution(object):
    def postorderTraversal(self, root):
        res = []
        def inorder(root):
            if not root:
                return 
            postorder(root.left)
            postorder(root.right)
            res.append(root.val)
        postorder(root)
        return res

2. 二叉树的最大深度

原题链接:104. 二叉树的最大深度 - 力扣(LeetCode)

class Solution(object):
    def maxDepth(self, root):
        if not root:
            return 0
        left_height = self.maxDepth(root.left)
        right_height = self.maxDepth(root.right)
        return max(left_height, right_height) + 1

3. 翻转二叉树

原题链接:226. 翻转二叉树 - 力扣(LeetCode)

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

4. 对称二叉树

原题链接:101. 对称二叉树 - 力扣(LeetCode)

class Solution(object):
    def isSymmetric(self, root):
        def check(left, right):
            if not left and not right:
                return True
            if not left or not right:
                return False
            if left.val != right.val:
                return False
            return check(left.left, right.right) and check(left.right, right.left)
        return check(root.left, root.right)

5. 二叉树的直径

原题链接:543. 二叉树的直径 - 力扣(LeetCode)

class Solution(object):
    def diameterOfBinaryTree(self, root):
        def dfs(root):
            if not root:
                return 0, 0
            ld, ldepth = dfs(root.left)
            rd, rdepth = dfs(root.right)
            return max(ld, rd, ldepth+rdepth), max(ldepth, rdepth) + 1
        return dfs(root)[0]

6. 二叉树的层序遍历

原题链接:102. 二叉树的层序遍历 - 力扣(LeetCode)

class Solution(object):
    def levelOrder(self, root):
        if not root:
            return []
        node = [root]
        res = []
        while len(node) > 0:
            res.append([i.val for i in node])
            node2 = []
            for i in node:
                if i.left:
                    node2.append(i.left)
                if i.right:
                    node2.append(i.right)
            node = node2
        return res

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

原题链接:108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)

class Solution(object):
    def sortedArrayToBST(self, nums):
        def dfs(left, right):
            if left > right:
                return
            mid = (left + right) // 2
            root = TreeNode(nums[mid])
            root.left = dfs(left, mid-1)
            root.right = dfs(mid+1, right)
            return root
        return dfs(0, len(nums)-1)

8. 验证二叉搜索树

原题链接:98. 验证二叉搜索树 - 力扣(LeetCode)

class Solution(object):
    def isValidBST(self, root, left=float('-inf'), right=float('inf')):
        if not root:
            return True
        x = root.val
        return left < x < right and self.isValidBST(root.left, left, x) and self.isValidBST(root.right, x, right)
# self.isValidBST(root.left, left, x):遍历左子树,右边界更新
# self.isValidBST(root.right, x, right):遍历右子树,左边界更新

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

原题链接:230. 二叉搜索树中第 K 小的元素 - 力扣(LeetCode)

# 先通过前序/中序/后序遍历转为list,而后利用list属性找第k个小的元素。
# 此代码使用前序遍历(根-左-右)
class Solution(object):
    def kthSmallest(self, root, k):
        res = [] 
        def preorder(root):
            if not root:
                return
            res.append(root.val)
            preorder(root.left)
            preorder(root.right)
            return res
        res = preorder(root)
        res.sort()
        return res[k-1]

10. 二叉树的右视图

原题链接:199. 二叉树的右视图 - 力扣(LeetCode)

class Solution(object):
    def rightSideView(self, root):
        # if len(res) == depth: res.append(root.val)
        # 先遍历右子树,再遍历左子树
        res = []
        def dfs(root, depth):
            if not root:
                return []
            if len(res) == depth:
                res.append(root.val)
            dfs(root.right, depth+1)
            dfs(root.left, depth+1)
            return res
        return dfs(root, 0)

11. 二叉树展开为链表

原题链接:114. 二叉树展开为链表 - 力扣(LeetCode)

# 按 ‘根-左-右’ 的前序遍历顺序展开
class Solution(object):
    def flatten(self, root):
        self.prev = TreeNode()
        def preorder(root):
            if not root:
                return []
            left, right = root.left, root.right
            self.prev.left = None
            self.prev.right = root
            self.prev = self.prev.right
            preorder(left)
            preorder(right)
            return self.prev
        preorder(root)

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

原题链接:105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

class Solution(object):
    def buildTree(self, preorder, inorder):
        if not preorder or not inorder:
            return
        root = TreeNode(preorder[0])
        index = inorder.index(root.val)
        root.left = self.buildTree(preorder[1:1+index], inorder[:index])
        root.right = self.buildTree(preorder[1+index:], inorder[1+index:])
        return root

13. 路径总和 III

原题链接:437. 路径总和 III - 力扣(LeetCode)

#         self.right = right
class Solution(object):
    def pathSum(self, root, targetSum):
        if not root:
            return 0
        def dfs(root, targetSum):
            if not root:
                return 0
            if root.val == targetSum:
                ans = 1
            else:
                ans =0
            return ans + dfs(root.left, targetSum-root.val) + dfs(root.right, targetSum-root.val) # 根节点+遍历左子树+遍历右子树
        return dfs(root, targetSum) + self.pathSum(root.left, targetSum) + self.pathSum(root.right, targetSum) #路径 不需要从根节点开始,也不需要在叶子节点结束

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

原题链接:236. 二叉树的最近公共祖先 - 力扣(LeetCode)

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        if not root or root==p or root==q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if left and right:
            return root
        if left:
            return left
        return right

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

原题链接:124. 二叉树中的最大路径和 - 力扣(LeetCode)

class Solution(object):
    def maxPathSum(self, root):
        if not root:
            return 0
        self.maximum = float('-inf')
        def dfs(root):
            if not root:
                return 0
            l_val = dfs(root.left)
            r_val = dfs(root.right)
            self.maximum = max(self.maximum, l_val + r_val + root.val)
            return max(0, max(l_val, r_val) + root.val)
        dfs(root)
        return self.maximum

二、图论

1. 岛屿数量

原题链接:200. 岛屿数量 - 力扣(LeetCode)

class Solution(object):
    def numIslands(self, grid):
        m, n = len(grid), len(grid[0])
        def dfs(grid, i, j):
            grid[i][j] = "0"
            for x, y in [[i+1, j], [i-1, j], [i, j+1], [i, j-1]]:
                if 0<=x<m and 0<=y<n and grid[x][y]=="1":
                    grid[x][y] = "0"
                    dfs(grid, x, y)

        res = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == "1":
                    res += 1
                    dfs(grid, i, j) 
        return res

2. 腐烂的橘子

原题链接:994. 腐烂的橘子 - 力扣(LeetCode)

class Solution(object):
    def orangesRotting(self, grid):
        if not grid:
            return 0
        if 1 not in sum(grid, []):
            return 0
            
        m, n = len(grid), len(grid[0])
        queue = []
        time = 0
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 2:
                    queue.append([i, j, time])

        while queue:
            i, j, time = queue.pop(0)
            for x, y in [[i+1, j], [i-1, j], [i, j+1], [i, j-1]]:
                if 0<=x<m and 0<=y<n and grid[x][y]==1:
                    grid[x][y] = 2
                    queue.append([x, y, time+1])

        if 1 in sum(grid, []):
            return -1
        return time 

3. 课程表

原题链接:207. 课程表 - 力扣(LeetCode)

# Python3实现本质是找有向无环图(无环:return True; 有环:return Flase)
class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        from graphlib import TopologicalSorter as TS
        ts = TS()
        for curr, pre in prerequisites:
            ts.add(curr, pre)
        return not ts._find_cycle()   # 不存在有向无环图

4. 实现 Trie (前缀树)

原题链接:208. 实现 Trie (前缀树) - 力扣(LeetCode)

class Trie(object):
    def __init__(self):  
        self.lst = []   

    def insert(self, word):
        self.lst.append(word)

    def search(self, word):
        if word in self.lst:
            return True
        else: return False
    def startsWith(self, prefix):
        lp = len(prefix)
        for word in self.lst:
            if word[:lp] == prefix:
                return True
        return False
    
# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)

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

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

相关文章

【计算机视觉】YOLO语义分割

一、语义分割简介 1. 定义 语义分割&#xff08;Semantic Segmentation&#xff09;是计算机视觉中的一项任务&#xff0c;其目标是对图像中的每一个像素赋予一个类别标签。与目标检测只给出目标的边界框不同&#xff0c;语义分割能够在像素级别上区分不同类别&#xff0c;从…

【SpringBoot + MyBatis + MySQL + Thymeleaf 的使用】

目录&#xff1a; 一&#xff1a;创建项目二&#xff1a;修改目录三&#xff1a;添加配置四&#xff1a;创建数据表五&#xff1a;创建实体类六&#xff1a;创建数据接口七&#xff1a;编写xml文件八&#xff1a;单元测试九&#xff1a;编写服务层十&#xff1a;编写控制层十一…

在ensp进行OSPF+RIP+静态网络架构配置

一、实验目的 1.Ospf与RIP的双向引入路由消息 2.Ospf引入静态路由信息 二、实验要求 需求&#xff1a; 路由器可以互相ping通 实验设备&#xff1a; 路由器router7台 使用ensp搭建实验坏境&#xff0c;结构如图所示 三、实验内容 1.配置R1、R2、R3路由器使用Ospf动态路由…

Redis安全与配置问题——AOF文件损坏问题及解决方案

Java 中的 Redis AOF 文件损坏问题全面解析 一、AOF 文件损坏的本质与危害 1.1 AOF 持久化原理 Redis 的 AOF&#xff08;Append-Only File&#xff09; 通过记录所有写操作命令实现持久化。文件格式如下&#xff1a; *2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n *3\r\n$3\r\nSET\r\…

3.第二阶段x64游戏实战-分析人物移动实现人物加速

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;2.第二阶段x64游戏实战-x64dbg的使用 想找人物的速度&#xff0c;就需要使用Ch…

Scala(三)

本节课学习了函数式编程&#xff0c;了解到它与Java、C函数式编程的区别&#xff1b;学习了函数的基础&#xff0c;了解到它的基本语法、函数和方法的定义、函数高级。。。学习到函数至简原则&#xff0c;高阶函数&#xff0c;匿名函数等。 函数的定义 函数基本语法 例子&…

什么是 Java 泛型

一、什么是 Java 泛型&#xff1f; 泛型&#xff08;Generics&#xff09; 是 Java 中一种强大的编程机制&#xff0c;允许在定义类、接口和方法时使用类型参数。通过泛型&#xff0c;可以将数据类型作为参数传递&#xff0c;从而实现代码的通用性和类型安全。 简单来说&…

Unity中根据文字数量自适应长宽的对话气泡框UI 会自动换行

使用Ugui制作一个可以根据文本数量自动调整宽度,并可以自动换行的文字UI 或者不要独立的Bg,那么一定要把bg的img设置成切片

【小也的Java之旅系列】02 分布式集群详解

文章目录 前言为什么叫小也 本系列适合什么样的人阅读正文单体优点缺点 CAP为什么CAP不可能全部满足&#xff1f;CAP 三选二 分布式事务分布式方案——SeataXA模式&#xff08;强一致&#xff09;AT模式&#xff08;自动补偿&#xff0c;默认模式&#xff09;TCC模式&#xff0…

Ubuntu里安装Jenkins

【方式1】&#xff1a;下载war包&#xff0c;直接运行&#xff0c;需提前搭建Java环境&#xff0c;要求11或17&#xff0c;不推荐&#xff0c;war包下载地址&#xff0c;将war包上传到服务器&#xff0c;直接使用命令启动 java -jar /data/jenkins/jenkins.war【方式2】&#…

C++包管理工具vcpkg的安装使用教程

前言 使用vcpkg可以更方便地安装各种库&#xff0c;省去配置的时间和配置失败的风险&#xff0c;类似python中的anaconda&#xff0c;懒人必备 参考 安装参考&#xff1a;https://bqcode.blog.csdn.net/article/details/135831901?fromshareblogdetail&sharetypeblogde…

微服务面试题:配置中心

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

Qt msvc2017程序无法用enigma vitrual box打包,用winrar打包

我们通常打包Qt程序用Enigma virtual box。这样我们的程序就可以在别的电脑上也能运行&#xff0c;但是有时候&#xff0c;我们发现Enigma virtual box在打包的时候&#xff0c;对于msvc2017需要编译的程序中引用webengineview模块&#xff0c;打包时候发现不能运行。 我们如何…

微服务集成测试 -华为OD机试真题(A卷、JavaScript)

题目描述 现在有n个容器服务&#xff0c;服务的启动可能有一定的依赖性&#xff08;有些服务启动没有依赖&#xff09;&#xff0c;其次&#xff0c;服务自身启动加载会消耗一些时间。 给你一个n n 的二维矩阵useTime&#xff0c;其中useTime[i][i]10表示服务i自身启动加载需…

Mac: 运行python读取CSV出现 permissionError

在MAC机器里&#xff0c;之前一直运行程序在某个指定的目录下读取excel和csv文件&#xff0c;没有出现错误&#xff0c;有一天突然出现错误&#xff1a;permissionError:[Errno 1] Operation not permitted&#xff0c; 具体错误信息如下&#xff1a; 经过调查得知&#xff0c…

UE5 学习笔记 FPS游戏制作30 显示击杀信息 水平框 UI模板(预制体)

文章目录 一制作单条死亡信息框水平框的使用创建一个水平框添加子元素调整子元素顺序子元素的布局插槽尺寸填充对齐 制作UI 根据队伍&#xff0c;设置文本的名字和颜色声明变量 将变量设置为构造参数根据队伍&#xff0c;设置文本的名字和颜色在构造事件中&#xff0c;获取玩家…

西门子TCP通讯过程中硬件连接突然断开

通信原理探秘又结合在工作中遇到的问题,关注到了通讯中的KeepAlive定时器的设置,所以做了如下实验。 硬件: 1513PLC TCP客户端 PC TCP服务器 前提条件:禁用PLC侧KeepAlive 程序: 测试流程: 打开PC端网络调试助手,设置为TCP服务器,打开链接; PC端打开WireShack软…

2025宁德时代测评Verify考什么?网申测评如何通过SHL笔试|附真题线上笔试考点、高分攻略、CATL新能源科技SHL测评宁德社招题目、面试攻略、求职建议

——职小豚 带你拆解新能源巨头招聘密码 一、宁德时代&#xff1a;新能源赛道「超级独角兽」 作为全球动力电池龙头&#xff0c;宁德时代&#xff08;CATL&#xff09;的江湖地位无需多言&#xff1a; 技术硬实力&#xff1a;麒麟电池、钠离子电池、无钴电池等黑科技加持&…

Spring Boot @RequestParam 解析参数时的常见问题及解决方案

1&#xff0c;遇到的问题&#xff1a;将后端接口写完后我想通过PostMan进行简单的测试一下&#xff0c;一不小心就遇到了这样的情况&#xff1a; org.springframework.web.bind.MissingServletRequestParameterException: Required Integer parameter contractId is not prese…

Firefox 浏览器同步一个账户和书签网址

Firefox 浏览器同步一个账户和书签网址 Firefox 支持跨设备接续浏览&#xff0c;可实现电脑、手机与平板无缝衔接。无论您在使用哪台设备上使用 Firefox&#xff0c;都能获取书签、浏览历史、保存的密码等信息。当然也能实现windows、ios、linux、android系统中安装firefox浏览…