Day22代码随想录(1刷) 二叉树

235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

 状态:完成,一开始没想到可以这么好的利用二叉搜索树的特性

思路:一开始就是想把两个节点的所有前辈都求出来放到一个数组里,然后对比最深的,因为是前序遍历,所以最后一个匹配的就是最深的前辈。然后看了解析之后发现原来可以这样子做,因为这是一颗二叉搜索树,要求的是[p,q]之间的两者之间的最深的祖先节点。因为这是一个二叉搜索树我们可以这样想什么时候就是这两个节点的最后一个共同祖先节点了,就是这个节点的值跟两个目标节点异号的时候,因为这个时候要找到两个节点就得向两边去寻找,所以此时可以写出以下的算法。

一开始:

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {ArrayList<TreeNode> plist=new ArrayList<>();ArrayList<TreeNode> qlist=new ArrayList<>();findRoot(plist,root,p);findRoot(qlist,root,q);TreeNode result=null;for(int i=0;i<plist.size();i++){for(int j=0;j<qlist.size();j++){if(plist.get(i)==qlist.get(j)){result=plist.get(i);}  }}return result;}public void findRoot(ArrayList<TreeNode> list,TreeNode root,TreeNode tar){if(root==null) return;list.add(root);if(root.val>tar.val) findRoot(list,root.left,tar);if(root.val<tar.val) findRoot(list,root.right,tar);}
}

看解析后:

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root.val>p.val&&root.val>q.val) root=lowestCommonAncestor(root.left,p,q);if(root.val<p.val&&root.val<q.val) root=lowestCommonAncestor(root.right,p,q);return root;}
}

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

 

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

示例 1:

输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]
解释:另一个满足题目要求可以通过的树是:

示例 2:

输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]

示例 3:

输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出:[4,2,7,1,3,5]

提示:

  • 树中的节点数将在 [0, 104]的范围内。
  • -108 <= Node.val <= 108
  • 所有值 Node.val 是 独一无二 的。
  • -108 <= val <= 108
  • 保证 val 在原始BST中不存在。

状态:没做出来

思路:用二叉树的特性去解题,插入二叉搜索树在元素不重复的情况下是不会改变二叉树的结构的。用递归去找这个值所在的位置上然后进行插入完成题目。

class Solution {TreeNode preNode=null;public TreeNode insertIntoBST(TreeNode root, int val) {if(root==null) return new TreeNode(val);if(root.val>val){root.left=insertIntoBST(root.left,val);}else if(root.val<val){root.right=insertIntoBST(root.right,val);}return root;}
}

450. 删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

示例 1:

输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0
输出: [5,3,6,2,4,null,7]
解释: 二叉树不包含值为 0 的节点

示例 3:

输入: root = [], key = 0
输出: []

提示:

  • 节点数的范围 [0, 104].
  • -105 <= Node.val <= 105
  • 节点值唯一
  • root 是合法的二叉搜索树
  • -105 <= key <= 105

进阶: 要求算法时间复杂度为 O(h),h 为树的高度。

状态:完成

思路:用一个节点记录遍历的前一个节点用于删除操作,还要面临一个问题就是如果删除的节点就是根节点怎么办呢,这时候想起在链表的时候删去头节点是用了一个虚拟节点作为头节点去做删除操作的,所以我们可以用一个dummyNode.left指向根节点。这是一颗二叉搜索树,根据他的性质可以很快找到这个节点出来,然后我们有了他上一个节点,开始进行我们的删除操作。首先要分他是在preNode的左边还是右边,左边跟右边是相反的,拿左边举例,我们要把preNode.left指向要删除节点的右边,这时就要考虑如果节点的左边存在并且待删除节点的左边也存在这时就会重叠了,因为根据二叉搜索树的特性待删除节点的左边肯定要比待删除节点的右边所有值都要小,所以只要遍历待删除节点的右节点的左边到最后一个把待删除节点的左边加进去就可以了,右边也是同理。最后返回dummyNode.left就完成了。

class Solution {TreeNode preNode=null;TreeNode dummyNode=new TreeNode(-1);int index=0;public TreeNode deleteNode(TreeNode root, int key) {if(index==0){dummyNode.left=root;preNode=dummyNode;}index++;if(root==null) return root;if(root.val==key){if(preNode.left==root){if(root.right!=null){TreeNode node=root.right;while(node.left!=null){node=node.left;}node.left=root.left;preNode.left=root.right;}else{System.out.println(root.left);preNode.left=root.left;}}else if(preNode.right==root){if(root.left!=null){TreeNode node=root.left;while(node.right!=null){node=node.right;}node.right=root.right;preNode.right=root.left;}else{preNode.right=root.right;}}return dummyNode.left;}else if(root.val>key){preNode=root;deleteNode(root.left,key);}else if(root.val<key){preNode=root;deleteNode(root.right,key);} return dummyNode.left;}
}

 感想:二叉树的题目开始越来越难了,也感觉越来越灵活了今天也学到了很多比如二叉搜索树的插入以及删除。继续加油!

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

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

相关文章

CI860K01 3BSE032444R1 参数说明书

ABB CI860K01 3BSE032444R1是一款ABB公司生产的通信接口模块。 这款模块是专为工业自动化环境设计的&#xff0c;能够在各种设备之间提供稳定和可靠的数据传输接口。它采用了先进的通信技术和严格的生产工艺&#xff0c;确保了产品的高质量和性能。此外&#xff0c;它的设计合…

插槽和自定义命令

自定义指令 自定义的指令,定义好之后,在标签内使用,当执行new Vue去模板的时候,看到自定义指令,会将下面的函数,等到特定执行Vue实例阶段触发.模板渲染之后.当触发时的传参的参数的第一个是所写的对象的DOM对象,第二个是是包含指令的对象,对象value是指令赋值.当把指令写到标签…

产品推荐 | 基于 ALINX XILINX ZYNQ-7000 XC7Z020 多网口 FPGA开发板

01、产品概述 此款开发板使用的是Xilinx公司的Zynq 7000系列的芯片&#xff0c;型号为XC7Z020-2CLG484I&#xff0c;5 路千兆以太网接口&#xff0c;支持多网口高速数据交换数据处理存储&#xff0c;视频传输处理以及工业控制等。内核 CPU搭载双核 ARM CORTEX-A9&#xff1b;在…

手把手教你绘画原型图:Axure的安装使用

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师&#xff0c;大模型&#xff0c;爬虫、ACM算法 &#x1f492; 公众号&#xff…

AI+云平台|全闪云底座迎战

AI融万物之势席卷而来 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 行业特点 AI场景中80%以上是小文件&#xff0c;以非结构化数据为…

docker学习笔记 四-----docker基本使用方法

基础命令奉上&#xff1a; 1、docker命令查询方法 docker --help 获取docker命令帮助 docker search --help 查询docker 子命令search的帮助 2、查询镜像 查询镜像 docker search 192.168.206.100:5000/mysql 查询指定服务器指定镜像 docker search mysql …

牛客JZ21-调整数组顺序使奇数位于偶数前面

目录 问题描述示例具体思路思路一 代码实现 问题描述 输入一个长度为 n 整数数组&#xff0c;实现一个函数来调整该数组中数字的顺序&#xff0c;使得所有的奇数位于数组的前面部分&#xff0c;所有的偶数位于数组的后面部分&#xff0c;并保证奇数和奇数&#xff0c;偶数和偶数…

LInux|命令行参数|环境变量

LInux|命令行参数|环境变量 命令行参数main的参数之argc&#xff0c;argv几个小知识<font color#0099ff size 5 face"黑体">1.子进程默认能看到并访问父进程的数据<font color#4b0082 size 5 face"黑体">2.命令行创建的程序父进程都是bash 环…

【Redis】快速入门 数据类型 常用指令 在Java中操作Redis

文章目录 一、简介二、特点三、下载与安装四、使用4.1 服务器启动4.2 客户端连接命令4.3 修改Redis配置文件4.4 客户端图形化界面 五、数据类型5.1 五种常用数据类型介绍5.2 各种数据类型特点 六、常用命令6.1 字符串操作命令6.2 哈希操作命令6.3 列表操作命令6.4 集合操作命令…

你的 Python 代码需要解释一下了!

Python 是一种相对简单的编程语言。它主要以解释型语言著称&#xff0c;这意味着每行代码都要通过解释器逐行执行。不过在某些时候&#xff0c;将 Python 代码翻译成计算机可以理解的内容&#xff0c;然后再逐行执行&#xff0c;可以减少繁琐。 在这种情况下&#xff0c;编译器…

PostgreSQL中控制文件的解析与恢复

最近遇到有人问起PG中控制文件的一些使用问题,总结了一下。 1、PG控制文件简介 1.1、存储的位置 它的路径位于: 相关信息,可以用命令pg_controldata得到: [10:41:27-postgres@centos2:/var/lib/pgsql/14/data/global]$ pg_controldata -D $PGDATA pg_control version …

三位数组合-第12届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第42讲。 三位数组合&#…