代码随想录 day 20 二叉树

第六章 二叉树part07

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

相对于 二叉树的最近公共祖先 本题就简单一些了,因为 可以利用二叉搜索树的特性。

题目链接/文章讲解:https://programmercarl.com/0235.二叉搜索树的最近公共祖先.html

视频讲解:https://www.bilibili.com/video/BV1Zt4y1F7ww

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

本题比想象中的简单,大家可以先自己想一想应该怎么做,然后看视频讲解,就发现 本题为什么比较简单了。

题目链接/文章讲解:https://programmercarl.com/0701.二叉搜索树中的插入操作.html

视频讲解:https://www.bilibili.com/video/BV1Et4y1c78Y

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

相对于 插入操作,本题就有难度了,涉及到改树的结构

题目链接/文章讲解:https://programmercarl.com/0450.删除二叉搜索树中的节点.html

视频讲解:https://www.bilibili.com/video/BV1tP41177us

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

题目链接

https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/description/

解题思路

1.因为是有序树,所以 如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组 一定是在 [p, q]区间的

2.只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是p 和 q的公共祖先。 那问题来了,一定是最近公共祖先吗?

证明一下:

因为是二叉搜索树,中间节点在[p, q]区间,如果遇到了第一个节点在这个区间:

2.1 向左都是小于这个节点的,所以左子树不可能存在q

2.2 向右都是大于这个节点的,所在右子树不可能存在p

所以遇到的第一个节点一定是p和q的最近公共祖先。

3.递归遍历顺序,本题就不涉及到 前中后序了(这里没有中节点的处理逻辑,遍历顺序无所谓了)

code

java 复制代码
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null){
            return null;
        }
        //中

        //左
        //根据二叉搜索树的特性,向左搜索
        if(root.val>p.val&&root.val>q.val){
            TreeNode left=lowestCommonAncestor(root.left,p,q);
            if(left!=null){
                return left;
            }
        }
        //右
         //根据二叉搜索树的特性,向右搜索
        if(root.val<p.val&&root.val<q.val){
            TreeNode right=lowestCommonAncestor(root.right,p,q);
            if(right!=null){
                return right;
            }
        }
        //此时就说明在p和q之间了
        return root;
    }

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

题目链接

https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/

解题思路

有多种有效的插入方式,还可以重构二叉搜索树,一下子吓退了不少人,可以不用考虑改变树结构的插入方式,那么就简单了,就说明解题的时候审题的重要性,有些可忽略有些不可忽略。
利用返回值完成新加入的节点与其父节点的赋值操作的思想:

通过递归函数返回值完成了新加入节点的父子关系赋值操作,下一层将节点返回,本层用root.left或root.right 接住
解题流程:

只要按照二叉搜索树的规则去遍历,遇到空节点就插入节点就可以了

根据二叉搜索树的特性,去判断它是向左递归还是向右

val<root.val 去左子树

val>root.val 去右子树

直到找到一个null值,说明找到了它的位置,这个null值的空节点就是这个val新节点,返回给递归函数赋值给腹父节点。

code

java 复制代码
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root==null){
            return new TreeNode(val);
        }
        if(val < root.val){
            root.left=insertIntoBST(root.left,val);
        }
        if(val > root.val){
            root.right=insertIntoBST(root.right,val);
        }
        return root;
    }

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

题目链接

https://leetcode.cn/problems/delete-node-in-a-bst/description/

解题思路

删除节点的操作是通过返回值来操作,通过递归返回值来把新节点赋值给父节点。

root==null 是终止条件 找到要删的点也是终止条件,找到删的点后要处理逻辑,最终返回新的节点给父节点。

分析下面几种情况,可以画图模拟下

分治递归,像是前序遍历

分治递归的核心思想是将一个问题分解为多个子问题分别求解,然后将子问题的解组合起来得到原问题的解

在前中后序这些遍历方法中,都遵循分治递归的思想:

分解问题:对每个节点,都将其左子树和右子树视为子问题。

解决子问题:通过递归调用,在子树上继续执行相同的遍历操作。

合并结果:根据遍历的顺序,将子树的遍历结果组合起来。

前序、中序和后序遍历都可以视为分治递归的具体应用。

code

java 复制代码
    public TreeNode deleteNode(TreeNode root, int key) {
        //1.没找到要删除的节点 返回null
        if(root==null){
            return null;
        }
        //找到要删除的节点
        if(root.val==key){
            //2.左右都未null 不需要额外处理直接返回null就是删除当前的节点
           if(root.left==null&&root.right==null){
              return null;
            //3.左右都不为null 把左节点放入到右节点的最左节点,分析搜索树的特性即可
           }else if(root.left!=null&&root.right!=null){
                TreeNode cur=root.right;
                while(cur.left!=null){
                    cur=cur.left;
                }
                cur.left=root.left;
              return root.right;
           //4.左不为null右为null 返回节点即可    
           }else if(root.left!=null){
                return root.left;
           //5.右不为null 左为null 返回节点即可    
           }else if(root.right!=null){
                return root.right;
           }
        }
        if(key < root.val){
            root.left=deleteNode(root.left,key);
        }
        if(key > root.val){
            root.right=deleteNode(root.right,key);
        }
        return root;
    }

扩展 根据数组构建二叉树

java 复制代码
public class BinaryTreeBuilder {


    // 根据数组构建二叉树
    public static TreeNode buildTree(Integer[] nodes) {
        if (nodes == null || nodes.length == 0) {
            return null;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        TreeNode root = new TreeNode(nodes[0]);
        queue.add(root);

        int i = 1;
        while (!queue.isEmpty() && i < nodes.length) {
            TreeNode current = queue.poll();

            if (i < nodes.length && nodes[i] != null) {
                current.left = new TreeNode(nodes[i]);
                queue.add(current.left);
            }
            i++;

            if (i < nodes.length && nodes[i] != null) {
                current.right = new TreeNode(nodes[i]);
                queue.add(current.right);
            }
            i++;
        }

        return root;
    }
}
    public static void main(String[] args) {
        TreeNode treeNode = BinaryTreeBuilder.buildTree(new Integer[]{3,2,5,null,null,4,10,null,null,8,15,7});
        new Solution().deleteNode(treeNode, 5);
    }
相关推荐
九圣残炎31 分钟前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge33 分钟前
Netty篇(入门编程)
java·linux·服务器
lulu_gh_yu37 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!1 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
Re.不晚1 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐1 小时前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。1 小时前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野1 小时前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航1 小时前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
confiself2 小时前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言