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

分析1.0 

二叉搜索树根节点元素值大小介于子树之间,所以只要找到第一个介于他俩之间的节点就行

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

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

分析1.0

搜索树插入的新节点替代了原本的空分叉

find 空分叉 插入

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

ps. 这里先确定是左边,再看是否为空的思路挺好

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

分析1.0

删除节点,找到节点分情况讨论

  1. 节点是叶子节点,直接删除
  2. 节点是分支节点,找左子树的最大值或右子树的最小值节点的pre节点,左树最大值节点可能有左子树,右树最小值节点可能有右子树,pre节点还可能是当前节点
    1. 有左子树有右子树 
    2. 有左子树无右子树
    3. 无左子树有右子树
  3. 删除节点要知道这个节点的父节点 每次递归前先令pre = 当前节点
  4. 还要清楚待删节点是父节点的左节点还是右节点,设置参数flag指示
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null){
return null;
}
TreeNode pre = new TreeNode(-1);
pre.left = root;
pre.right = root;
return delete(root, key, pre, 0);
} public TreeNode delete(TreeNode root, int key, TreeNode pre, int flag){
if(root == null){
return null;
}
if(key > root.val){
flag = 1;
pre = root;
delete(root.right, key, pre, flag);
}else if(key < root.val){
flag = -1;
pre = root;
delete(root.left, key, pre, flag);
}else {
// 是叶节点
if(root.left == null && root.right == null){
if(pre.val == -1){
return null;
}
if(flag == -1){
pre.left = null;
}else{
pre.right = null;
}
}
// 分支节点 有左子树没右子树 有左子树有右子树 找左子树最大节点的父节点
else if(root.left != null){
TreeNode target = findLeftTree(root.left, root);
// 如果target是左子树树根-左子树无右子树
int swap = 0;
if(target.val == root.val){
swap = target.left.val;
target.left = root.left.left;
}else{
swap = target.right.val;
// 可能最大节点target.right有左子树
target.right = target.right.left;
}
//System.out.println("pre节点为"+pre.val);
if(flag == -1){
pre.left.val = swap;
}else{
pre.right.val = swap;
}
}
// 分支节点 有右子树没左子树
else if(root.right != null && root.left == null){
TreeNode target = findRightTree(root.right, root);
int swap = 0;
if(target.val == root.val){
swap = target.right.val;
target.right = target.right.right;
}else{
swap = target.left.val;
target.left = target.left.right;
}
//System.out.println("target节点为"+pre.val);
if(flag == -1){
pre.left.val = swap;
}else{
pre.right.val = swap;
}
}
// 分支节点
}
return root;
}
// pre为待删除分支节点 左子树不为空 右子树空 找左子树最大节点
public TreeNode findLeftTree(TreeNode root, TreeNode pre){
//System.out.print("以"+root.val+"为根节点的树的最大节点为");
while(root.right != null){
pre = root;
root = root.right;
}
//System.out.println(root.val+"target节点为"+pre.val);
return pre;
}
// pre为待删除分支节点 右子树不为空 找右子树最小节点
public TreeNode findRightTree(TreeNode root, TreeNode pre){
//System.out.print("以"+root.val+"为根节点的树的最大节点为------");
while(root.left != null){
pre = root;
root = root.left;
}
//System.out.println(root.val+"它的pre节点为"+pre.val);
return pre;
}
}

lieetcode 上看到一个思路

如果目标节点大于当前节点值,则去右子树中删除;
如果目标节点小于当前节点值,则去左子树中删除;
如果目标节点就是当前节点,分为以下三种情况:
其无左子:其右子顶替其位置,删除了该节点;
其无右子:其左子顶替其位置,删除了该节点;
其左右子节点都有:其左子树转移到其右子树的最左节点的左子树上,然后右子树顶替其位置,由此删除了该节点。

总结

  1. 头脑中要有一棵树,树形象上的特点,遍历序列上的特点
  2. 一定要先想清楚代码逻辑、循环逻辑、递归逻辑再继续
  3. 我的做题思维通常都是用代码模拟人脑

常用变量名增量更新

size、val、ans、cnt、cur、pre、next、left、right、index、gap、tar、res、src、len、start、end、flag、ch

最新文章

  1. 深度剖析 | 基于大数据架构的BI应用
  2. 《JavaScript语言精粹》小记
  3. Codeforces 1C Ancient Berland Circus
  4. 08---Net基础加强
  5. Linux学习笔记(6)-工作管理
  6. MVC项目中如何判断用户是在用什么设备进行访问
  7. rovio 视觉里程计的笔记
  8. springMVC中使用POI方式导出excel至客户端、服务器实例
  9. 一个蒟蒻对FFT的理解(蒟蒻也能看懂的FFT)
  10. 使用nio遍历文件夹
  11. &quot;每日一道面试题&quot;.net托管堆是否会存在内存泄漏的情况
  12. JQuery 选择某个td中第二个a标签 控制特殊样式
  13. Codeforces Gym 101190M Mole Tunnels - 费用流
  14. influxdb问题解决
  15. v-on事件绑定指令
  16. MySQL基本使用
  17. 动态设置和访问cxgrid列的Properties
  18. 【Alpha】第四次Scrum meeting
  19. KVM磁盘镜像qcow2、raw、vmdk等格式区别(转)
  20. commons-logging log4j logback 知识点

热门文章

  1. .NET 6 中外部引用项目NU1105异常问题解决
  2. Python开发Brup插件检测SSRF漏洞和URL跳转
  3. STM32外部中断(EXTI)控制LED亮灭的代码
  4. 如何在SpringBoot中优雅地重试调用第三方API?
  5. Java7提供的Fork/Join框架实现高并发程序,你会使用吗?
  6. 【机器学习】李宏毅——Explainable ML(可解释性的机器学习)
  7. 11、lombok日志记录
  8. MVP、原型、概念验证,傻傻分不清楚?
  9. [OpenCV实战]33 使用OpenCV进行Hough变换
  10. 一文搞定Spring Task