当前位置: 首页 > news >正文

二刷力扣--二叉树(2)

226.翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
使用递归解决。

  1. 确定函数参数和返回值
    函数参数为当前节点cur。无返回值。
def dd(cur):
  1. 确定终止条件。当前节点为空则终止。
if not cur:return    
  1. 单层逻辑
    反转当前节点的左右,然后递归调用cur.left, cur.right
   def dd(cur):if not cur:return cur.left, cur.right = cur.right, cur.leftdd(cur.left)dd(cur.right)

完整代码如下:

class Solution:def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:def dd(cur):if not cur:return cur.left, cur.right = cur.right, cur.leftdd(cur.left)dd(cur.right)dd(root)return root

101.对称二叉树

给你一个二叉树的根节点 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 isSymmetric(self, root: Optional[TreeNode]) -> bool:def symmetric_list(lst):length = len(lst)i = 0j = length-1while i < j:if lst[i] != lst[j]:return Falsei += 1j -= 1return Trueres = []if not root:return resqueue = deque()queue.append(root)while len(queue) > 0:next_list = []length = len(queue)for i in range(length):node = queue.popleft()if node.left:queue.append(node.left)next_list.append(node.left.val)else:next_list.append(-9999)if node.right:queue.append(node.right)next_list.append(node.right.val)else:next_list.append(-9999)if not symmetric_list(next_list):return Falsereturn True

递归方式有点绕,因为要判断的是轴对称。

  1. 函数参数和返回值。
    参数是左子节点和右子节点。返回值是 bool值,表示是否当前节点是否轴对称。
def compare(left, right):  
  1. 终止条件。
    左右节点全为空或某个为空时,则可以判断出当前节点的左右是否是对称的了。
if not left and not right:return True
elif not left or not right:return False  
  1. 单层逻辑
return    left.val == right.val and \compare(left.left, right.right) and compare(left.right, right.left) 

104.二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

层序遍历非常直接,遍历的层数就是深度。

class Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:res = []if not root:return resqueue = deque()queue.append(root)while len(queue) > 0:sub_list = []length = len(queue) # 注意for i in range(length):node = queue.popleft()sub_list.append(node.val)if node.left:queue.append(node.left)if node.right:queue.append(node.right)res.append(sub_list)return resdef maxDepth(self, root: Optional[TreeNode]) -> int:res = self.levelOrder(root)return len(res)

递归更简单:

  1. 函数参数和返回值。
    参数为当前节点node。返回值为int值,表示节点的深度。
  2. 终止条件
    节点为空时,返回0.
  3. 单层逻辑
    max(左节点深度,右节点深度) +1
class Solution:def maxDepth(self, root: Optional[TreeNode]) -> int:def depth(node):if not node:return 0leftDepth = depth(node.left)rightDepth = depth(node.right)return max(leftDepth, rightDepth)+1return depth(root)
  • 二叉树节点的深度:指从节点到该节点最长简单路径边的条数。
  • 二叉树节点的高度:指从该节点叶子节点最长简单路径边的条数。
    本题可以使用前序遍历(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度
    而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。

111.二叉树的最小深度

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

这题层序遍历还是很简单,因为每遍历一层就对应深度+1。如果找到了叶子节点就可以终止遍历返回当前深度了。

class Solution:def minDepth(self, root: Optional[TreeNode]) -> int:if not root:return 0queue  = deque()queue.append(root)depth = 0while queue:depth += 1length = len(queue)for i in range(length):node = queue.popleft()if all([not node.left, not node.right]):return depth for nextnode in [node.left, node.right]:if nextnode:queue.append(nextnode)return depth

递归方式。
递归方式和104求最大深度差很多。最小深度必须是根节点到叶子节点的长度,如果左子树为空,右子树不为空,则只能通过右子树到达叶子节点(1+rightDepth)。

递归公式:

  1. 函数参数和返回值。
    参数为当前节点node。返回值为int值,表示节点的深度。
  2. 终止条件
    节点为空时,返回0.
  3. 单层逻辑
    如果只有右子树,返回 1+rightDepth
    如果只有左子树,返回 1+leftDepth
    否则,返回 min(左节点深度,右节点深度) +1
class Solution:def minDepth(self, root: Optional[TreeNode]) -> int:def getDepth(node: Optional[TreeNode]) -> int:if  not node :return 0leftDepth = getDepth(node.left)rightDepth = getDepth(node.right)if not node.left and node.right :return 1+ rightDepthif not node.right and node.left:return 1+ leftDepthreturn  1 + min(leftDepth, rightDepth)return getDepth(root)

222.完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

遍历一次就知道节点个数了。
但是这样就没有用到完全二叉树的性质。

完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

递归公式:

  1. 函数参数和返回值。
    参数是当前节点。返回值是当前节点为根节点的树的节点个数。

  2. 终止条件
    如果节点为None,返回0。

  3. 单层逻辑
    判断当前节点是不是满二叉树,是满二叉树则直接用公式2^树深度 - 1 返回节点数。否则递归处理左右子树,返回左子树节点数 + 右子树节点数 + 1。

class Solution:def countNodes(self, root: Optional[TreeNode]) -> int:if not root:return 0# 判断当前节点是不是满二叉树leftHeight, rightHeight = 0, 0left, right = root.left, root.rightwhile left:left = left.leftleftHeight += 1while right:right = right.rightrightHeight += 1# 是满二叉树,则用公式计算if leftHeight == rightHeight:return (2 << leftHeight) -1# 否则递归处理left, rightreturn self.countNodes(root.left) + self.countNodes(root.right) + 1

110.平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。

  • 二叉树节点的深度:指从节点到该节点最长简单路径边的条数。
  • 二叉树节点的高度:指从该节点叶子节点最长简单路径边的条数。

LeetCode上的不是按照路径数,而是按照节点数计算。

求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)。

递归公式

  1. 函数参数和返回值
    参数为当前节点,返回值为节点的高度。返回值为-1时表示不是平衡二叉树。
  2. 终止条件
    节点为None,返回0。
  3. 单层逻辑
    求左子树高度,如果为-1,则已经不平衡了,返回-1.
    求右子树高度,如果为-1,则已经不平衡了,返回-1.
    如果左右子树高度差>1,不平衡,返回-1.
    否则返回当前节点的高度,1 + max(leftDepth, rightDepth)
class Solution:def isBalanced(self, root: Optional[TreeNode]) -> bool:def getHeight(node):if not node:return 0leftDepth = getHeight(node.left)if leftDepth == -1: return -1rightDepth = getHeight(node.right)if rightDepth == -1: return -1if abs(leftDepth - rightDepth) > 1:return -1else:return  1 + max(leftDepth, rightDepth)return not getHeight(root) == -1

257.二叉树的所有路径

任意顺序 ,返回所有从根节点到叶子节点的路径。

递归+回溯。
递归公式

  1. 参数和返回值
    参数是当前节点、路径、(存放结果的数组)。返回值无。
  2. 终止条件
    到达叶子节点。
  3. 单层逻辑
    添加当前节点,递归(+回溯)遍历左子树和右子树。
class Solution:def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:def traversal(cur, path, result):path.append(cur.val)   # 终止条件:到达叶子节点了     if not any([cur.left, cur.right]):sPath = ""for n in path:sPath += str(n)sPath += "->"sPath = sPath[:-2]result.append(sPath)return# 左子树 if cur.left:traversal(cur.left, path, result)path.pop() # 回溯# 右子树  if cur.right:traversal(cur.right, path, result)path.pop()result = []path = []if not root:return resulttraversal(root, path, result)return result

404.左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。
左叶子:是父节点的左节点,并且是叶子节点。

递归公式:

  1. 函数参数和返回值
    参数是当前节点,返回值是当前节点的左叶子之和。
  2. 终止条件
    当前节点为None,返回0.
  3. 单层逻辑
    如果当前节点是左叶子,则要加入当前节点的值。然后加上左子树的左叶子和,右子树的左叶子和。
class Solution:def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:def getLeft(node):if not node:return 0leftValue = getLeft(node.left)rightValue = getLeft(node.right)midValue = 0# 左叶子:# 它是父节点的左节点,同时它是叶子节点if node.left and node.left.left == None and node.left.right ==None:midValue =  node.left.val return midValue + leftValue + rightValuereturn getLeft(root)

513.找树左下角的值

给定一个二叉树的 根节点 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 levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:res = []if not root:return resqueue  = deque()queue.append(root)while queue:sub_list  = []length = len(queue)for i in range(length):node = queue.popleft()sub_list.append(node.val)for nextnode in [node.left, node.right]:if nextnode:queue.append(nextnode)res.append(sub_list)return resdef findBottomLeftValue(self, root: Optional[TreeNode]) -> int:return self.levelOrder(root)[-1][0]

递归方式。
递归找最底层最左的节点,需要知道层数。
递归公式:

  1. 函数参数和返回值。
    参数是当前节点和当前层数。
  2. 终止条件
    到达叶子节点。
  3. 单层逻辑
    递归处理左子树和右子树,深度+1.
class Solution:def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:maxDepth = -11111 # 最大深度maxLeftValue = 0 # 最深层 最左的节点值def traversal(root, depth):nonlocal maxDepth, maxLeftValue# 终止条件: 到达叶子if not root.left and not root.right:# 深度是最深的,更新答案if depth > maxDepth:maxDepth = depthmaxLeftValue = root.valreturn# 递归处理左右if root.left:traversal(root.left, depth+1) # 隐藏回溯if root.right:traversal(root.right, depth+1)return traversal(root,0)return maxLeftValue

112.路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false
递归公式:

  1. 函数参数和返回值
    参数:当前节点root,目标和targetSum。
    返回值:bool值,表示是否满足题目要求。
  2. 终止条件:
    当前节点为None,返回False
  3. 单层逻辑:
    如果是叶子节点,判断当前值和目标值是否相等。
    否则对左、右子数递归判断。
class Solution:def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:if not root:return Falseif not root.left and not root.right:return root.val == targetSumreturn self.hasPathSum(root.left, targetSum-root.val) or self.hasPathSum(root.right, targetSum-root.val)

相关文章:

二刷力扣--二叉树(2)

226.翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 使用递归解决。 确定函数参数和返回值 函数参数为当前节点cur。无返回值。 def dd(cur):确定终止条件。当前节点为空则终止。 if not cur:return 单层逻辑 反转当前…...

【C++ Efficiency】使用运算符的复合形式取代其单独形式,效率更高

//单独形式 x x y; x x - y; //也可以写为复合形式 x y; x - y;效率问题 一般而言&#xff0c;复合操作符比其对应的单独形式效率高&#xff1a;因为单独形式需要返回一个新的对象&#xff0c;就会产生一个临时对象的构造和析构成本&#xff0c;复合版本则是直接写入左…...

uview的真机演示,微信小程序,当两个input框的时候,从一个input切换到两一个input的时候,键盘调不起来

项目场景&#xff1a; 项目相关背景&#xff1a; 例如&#xff1a;uview的真机演示&#xff0c;微信小程序&#xff0c;当两个input框的时候&#xff0c;从一个input切换到两一个input的时候&#xff0c;键盘调不起来 问题描述 遇到的问题&#xff1a; 例如&#xff1a;切…...

信息化发展58

安全系统 X 轴是“ 安全机制” 。安全机制可以理解为提供某些安全服务&#xff0c; 利用各种安全技术和技巧&#xff0c; 所形成的一个较为完善的结构体系。如“ 平台安全” 机制&#xff0c; 实际上就是指安全操作系统、安全数据库、应用开发运营的安全平台以及网络安全管理监…...

2023前端面试题

一.HTML篇 1.HTML是什么&#xff1f;它的缩写代表什么&#xff1f; HTML代表"超文本标记语言"&#xff08;Hypertext Markup Language&#xff09;&#xff0c;它是一种用于创建网页结构和内容的标记语言。 2.HTML文档的基本结构是什么&#xff1f; 基本的HTML结构包…...

Spring整合第三方框架-MyBatis原始操作代码

建议自己写一下 实体类&#xff0c;用于封装数据库数据 package com.example.pojo;import java.util.Date;public class Emp {private Integer id;private String username;private String password;private String name;private Integer gender;private String image;privat…...

比特币 ZK 赏金系列:第 2 部分——查找哈希冲突

在我们的零知识赏金 (ZKB) 系列的第二部分中&#xff0c;我们将其应用于解决哈希冲突难题。在这样的谜题中&#xff0c;两个不同的输入散列到相同的输出。此类赏金可用于&#xff1a; 充当煤矿中的金丝雀&#xff0c;给我们一个有价值的提醒。存在冲突是散列函数较弱的标志&…...

Android9底部导航栏出现空白按钮问题分析

Android9底部导航栏出现空白按钮问题分析 底部导航栏的初始化 进入NavigationBarView初始化: 进入NavigationBarView的onFinishInflater进入NavigationBarInflaterView NavigationBarInflaterView加载单个的button回到NavigationFragment的创建流程 多次调用NavigationBarView的…...

秦时明月沧海手游阵容推荐,秦时明月沧海角色强度

秦时明月沧海角色强度如何&#xff1f;在秦时明月沧海手游中&#xff0c;您可以从大量的角色卡牌中选择并发展&#xff0c;为了顺利通过各种副本&#xff0c;玩家们需要精心搭配阵容。那么&#xff0c;具体该如何配置最强的角色呢&#xff1f; 下面&#xff0c;小编将带各位玩家…...

基于微信小程序的大学生科技竞赛竞技报名系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…...

crypto:摩丝

题目 根据题目所给的压缩包下载后解压&#xff0c;打开文本提示 摩斯密码&#xff0c;对照表可解码得到flag...

Docker最基本使用

1 安装&#xff1a; sudo apt-get -y install docker.io测试&#xff1a; sudo docker run hello-world成功&#xff1a; Hello from Docker! This message shows that your installation appears to be working correctly.2 查看 查看已有镜像&#xff1a; sudo docker i…...

vue2.x 迭代更新项目去掉缓存处理

找到build文件下的webpack.prod.conf.js文件 定义一个常量version const Version new Date().getTime(); 然后在.js和.css前面加上.${Version}就可以了&#xff08;注意得把原本的换成&#xff09;...

Linux高性能服务器编程 学习笔记 第八章 高性能服务器程序框架

TCP/IP协议在设计和实现上没有客户端和服务器的概念&#xff0c;在通信过程中所有机器都是对等的。但由于资源&#xff08;视频、新闻、软件等&#xff09;被数据提供者所垄断&#xff0c;所以几乎所有网络应用程序都采用了下图所示的C/S&#xff08;客户端/服务器&#xff09;…...

技术对比:Flutter vs. 传统桌面应用开发框架

在移动应用开发领域&#xff0c;Flutter已经赢得了广泛的认可和采用&#xff0c;成为了跨平台移动应用开发的瑞士军刀。然而&#xff0c;Flutter的魅力并不仅限于移动平台&#xff0c;它还可以用于开发桌面应用程序&#xff0c;为开发人员提供了一种全新的选择。本文将深入探讨…...

[C++ 网络协议] 异步通知I/O模型

1.什么是异步通知I/O模型 如图是同步I/O函数的调用时间流&#xff1a; 如图是异步I/O函数的调用时间流&#xff1a; 可以看出&#xff0c;同异步的差别主要是在时间流上的不一致。select属于同步I/O模型。epoll不确定是不是属于异步I/O模型&#xff0c;这个在概念上有些混乱&a…...

Postgresql事务测试

参考一个事务中 可以查询自己未提交的数据吗_最详细MySQL事务隔离级别及原理讲解&#xff01;&#xff08;二&#xff09;-CSDN博客 一个事务中 可以查询自己未提交的数据吗_趣说数据库事务隔离级别与原理_weixin_39747293的博客-CSDN博客 【MySql&#xff1a;当前读与快照读…...

【数据结构--排序】冒泡排序,选择排序,插入排序

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

vue pc端/手机移动端 — 下载导出当前表格页面pdf格式

一、需求&#xff1a;在手机端/pc端实现一个表格页面&#xff08;缴费单/体检报告单等&#xff09;的导出功能&#xff0c;便于用户在本地浏览打印。 二、实现&#xff1a;之前在pc端做过预览打印的功能&#xff0c;使用的是print.js之类的方法让当前页面直接唤起打印机的打印预…...

125. 验证回文串 【简单题】

题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &#xff1b;否则…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...