day20 第六章 二叉树part07

devtools/2024/11/23 1:47:56/

第一题:235. 二叉搜索树的最近公共祖先

解题思路

  1. 利用二叉搜索树的特性
    二叉搜索树的特点是左子树的所有节点值都小于根节点值,右子树的所有节点值都大于根节点值。基于这个特性,我们可以通过比较根节点与要查找的两个节点 p 和 q 的值的大小关系,来确定最近公共祖先所在的子树方向。
  2. 递归法思路
    • 首先,比较根节点 root 的值和 pq 的值大小。
    • 如果 root.val 大于 p.val 且大于 q.val,这意味着 p 和 q 都在 root 的左子树中,那么它们的最近公共祖先也必然在左子树,所以继续在左子树中递归调用 lowestCommonAncestor 方法去寻找。
    • 反之,如果 root.val 小于 p.val 且小于 q.val,说明 p 和 q 都在 root 的右子树中,就继续在右子树中递归查找。
    • 而当出现 root.val 的值介于 p.val 和 q.val 之间(或者等于其中某一个的值,因为节点也可以是它自己的祖先)时,此时这个 root 节点就是 p 和 q 的最近公共祖先,直接返回 root 即可。
  3. 迭代法思路(代码中被注释部分)
    和递归法类似,也是通过不断比较根节点与 pq 的值大小来决定遍历方向。在一个 while 循环中,如果 root.val 大于 p.val 且大于 q.val,就将 root 指向其左子树节点(即 root = root.left);如果 root.val 小于 p.val 且小于 q.val,就将 root 指向其右子树节点(即 root = root.right);直到找到 root.val 介于 p.val 和 q.val 之间(或等于其中某一个值)的情况,此时跳出循环,返回这个 root 节点作为最近公共祖先。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {// 递归法if(root.val > p.val && root.val > q.val){return lowestCommonAncestor(root.left,p,q);}if(root.val < p.val && root.val < q.val){return lowestCommonAncestor(root.right,p,q);}return root;// //迭代法// while(true){//     if(root.val > p.val && root.val > q.val){//         root = root.left;//     }else if(root.val < p.val && root.val < q.val){//         root = root.right;//     }else{//         break;//     }// }// return root;}
}

第二题:701.二叉搜索树中的插入操作

解题思路

  1. 利用二叉搜索树特性确定插入位置
    二叉搜索树的关键特性是左子树的所有节点值都小于根节点值,右子树的所有节点值都大于根节点值。基于此特性,要插入一个新值 val,我们就通过不断比较该值与当前节点(从根节点开始)值的大小关系,来决定新值应该插入到当前节点的左子树还是右子树中。
  2. 递归思路
    • 首先判断当前传入的根节点 root 是否为空。如果为空(意味着已经遍历到合适的位置可以插入新节点了),那就创建一个值为 val 的新节点并返回,这个新节点就是插入后的二叉搜索树的一部分了。
    • 接着,如果 root.val 小于 val,说明新值 val 应该插入到当前根节点的右子树中,那么就对右子树进行递归操作,也就是通过 root.right = insertIntoBST(root.right, val) 这句代码,以当前节点的右子节点作为新的 “根节点” 继续去判断新值 val 在这个右子树中的合适插入位置,不断重复这个过程,直到找到合适的空节点位置插入新值。
    • 反之,如果 root.val 大于 val,那就意味着新值 val 要插入到当前根节点的左子树中,通过 root.left = insertIntoBST(root.left, val) 对左子树进行递归查找合适的插入位置。
    • 最后,无论新值插入到了左子树还是右子树,最终都返回根节点 root,这样就能保证返回的是整个插入新值后的二叉搜索树的根节点,因为经过递归操作后,树的结构已经正确更新了。

代码 

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {if(root == null){//如果当前节点为空,也就是意味着val找到了合适的位置,此时创建节点直接返回return new TreeNode(val);}if(root.val < val){root.right = insertIntoBST(root.right,val);//递归创建右子树}else if(root.val > val){root.left = insertIntoBST(root.left,val);//递归创建左子树}return root;}
}

 第三题:450.删除二叉搜索树中的节点

解题思路

  1. 整体思路概述
    要删除二叉搜索树中的指定节点并保持二叉搜索树的性质不变,需要先找到该节点,然后根据节点的不同情况(比如有无左子树、右子树等)来进行相应的删除操作,最后返回更新后的二叉搜索树的根节点。

  2. 寻找要删除的节点
    通过递归地比较当前节点 root 的值和要删除的 key 值的大小关系来查找目标节点。如果 root.val > key,说明要删除的节点可能在当前节点的左子树中,那就继续在左子树里递归查找,即执行 root.left = deleteNode(root.left, key);同理,如果 root.val < key,则在右子树里递归查找,执行 root.right = deleteNode(root.right, key)。当 root.val == key 时,就意味着找到了要删除的节点,接下来要进行具体的删除操作。

  3. 删除节点的不同情况处理

    • 情况一:待删除节点没有左子树
      此时直接返回该节点的右子树即可,因为这样就能将原节点从树中移除,并且保持二叉搜索树的性质,右子树中的节点原本就都大于原节点值,符合二叉搜索树的定义。
    • 情况二:待删除节点没有右子树
      同理,直接返回该节点的左子树,左子树中的节点都小于原节点值,也能保证二叉搜索树性质不变。
    • 情况三:待删除节点既有左子树又有右子树
      为了维持二叉搜索树的结构和性质,一种常见做法是用待删除节点右子树中的最小节点(也就是右子树中最左边的节点,它是右子树中值最小的,大于原节点左子树所有值)来替换待删除节点。具体操作就是先找到右子树中的最小节点 cur(通过不断访问左子节点来找到最左边的节点),然后将这个最小节点的左子树设置为待删除节点的左子树(因为这个最小节点原本没有左子树,且它大于原节点左子树的值,这样替换能保证二叉搜索树性质),最后让原节点指向其右子树(也就是用右子树整体替换掉原节点),并返回更新后的根节点。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode deleteNode(TreeNode root, int key) {if(root == null) return root;if(root.val == key){if(root.left == null) {return root.right;}else if(root.right == null){return root.left;}else{TreeNode cur = root.right;while(cur.left != null){cur = cur.left;}cur.left = root.left;root = root.right;return root;}} if(root.val > key) root.left = deleteNode(root.left,key);if(root.val < key) root.right = deleteNode(root.right,key);return root;}
}

 


http://www.ppmy.cn/devtools/136169.html

相关文章

48v72v-100v转12v 10A大功率转换电源方案CSM3100SK

如今市场上电机的应用极为广泛&#xff0c;众多电机所需供电量较大。当电机的输入端为多节电池串联或由不同材质的电池供电时&#xff0c;需要将此电压稳定至 12V 或其他特定电压来为电机供电。而且&#xff0c;在电机堵转或急停急启时&#xff0c;瞬间电流会变得非常大。倘若所…

Javaweb梳理16——HTMLCSS使用

Javaweb梳理16——HTML&CSS使用 16 快速入门16.1 基础标签16.2 图片、音频、视频标签16.3 超链接标签16.4 列表标签16.5 表格标签16.6 布局标签16.7 表单标签16.8 type取值 16 快速入门 1.新建文本文件&#xff0c;后缀名改为 .html/.htm 2.编写 HTML结构标签 3.在<bod…

SQL注入注入方式(大纲)

SQL注入注入方式&#xff08;大纲&#xff09; 常规注入 通常没有任何过滤&#xff0c;直接把参数存放到SQL语句中。 宽字节注入 GBK 编码 两个字节表示一个字符ASCII 编码 一个字节表示一个字符MYSQL默认字节集是GBK等宽字节字符集 原理&#xff1a; 设置MySQL时错误配置…

sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地

Sharding-JDBC&#xff08;现为Apache ShardingSphere的一部分&#xff09;允许你自定义分片策略。以下是一个使用Spring框架实现的demo&#xff0c;该demo展示了如何以公司ID作为分片键&#xff0c;并将公司ID对应的表后缀存入Redis中&#xff0c;以实现数据的分片存储。 步骤…

MySQL的表的约束以及查询

本篇文章继续给大家梳理MySQL的操作 目录 表的约束 空属性 默认值 列描述 0填充 主键 主键常识 添加主键 删除主键 复合主键 自增长 唯一键 外键 单/多行输入与全/指定列的插入 全列输入 单行输入 多行插入 指定列插入 单行输入 多行插入 插入否则更新 替换…

✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本

api.js //封装ajax方法 import $g from "../sg";//vue项目使用 import $ from jquery;//(提示&#xff1a;原生开发页面请前往https://jquery.com下载最新版jQuery) import { Message } from "element-ui";//element项目使用 // import axios from "…

东胜物流软件 GetDataListCA SQL注入漏洞复现

0x01 产品描述: ‌ 东盛物流软件‌是一款专业的物流管理软件,旨在帮助企业高效地管理物流运输、仓储和配送等环节。该软件通过实现订单跟踪、库存管理、运输路线优化等功能,提高物流效率,降低成本,提升客户满意度,从而提升企业竞争力‌。0x02 漏洞描述: 东胜物流软…

2.13 转换矩阵

转换矩阵引用了库nalgebra&#xff0c;使用时研究具体实现。 use std::ops;use nalgebra::Perspective3;use crate::Scalar;use super::{Aabb, LineSegment, Point, Triangle, Vector};/// An affine transform #[repr(C)] #[derive(Debug, Clone, Copy, Default)] pub struct…