首页 > 编程语言 >代码随想录算法训练营第二十天 | 235. 二叉搜索树的最近公共祖先、701. 二叉搜索树中的插入操作、450. 删除二叉搜索树中的节点

代码随想录算法训练营第二十天 | 235. 二叉搜索树的最近公共祖先、701. 二叉搜索树中的插入操作、450. 删除二叉搜索树中的节点

时间:2025-01-15 17:29:46浏览次数:3  
标签:right target val root cur 二叉 搜索 树中 left

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

题目链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/description/
文档讲解:https://programmercarl.com/0235.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html
状态:已完成

思路:利用二叉搜索树的性质判断p和q在哪颗子树中很方便,基于这一结论进行递归

时间复杂度: O ( l o g N ) O(logN) O(logN);空间复杂度: O ( l o g N ) O(logN) O(logN)

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

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

题目链接:https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/
文档讲解:https://programmercarl.com/0701.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%8F%92%E5%85%A5%E6%93%8D%E4%BD%9C.html
状态:已完成

思路:利用二叉搜索树的性质,寻找val的父节点,因此需要使用双指针遍历二叉树
时间复杂度: O ( l o g N ) O(logN) O(logN);空间复杂度: O ( 1 ) O(1) O(1)

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null)
            return new TreeNode(val);

        TreeNode cur = root, last = root;
        while(cur != null){
            if(cur.val > val){
                last = cur;
                cur = cur.left;
            }else{
                last = cur;
                cur = cur.right;
            }
        }
        if(last.val > val)
            last.left = new TreeNode(val);
        else
            last.right = new TreeNode(val);
        return root;
    }
}

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

题目链接:https://leetcode.cn/problems/delete-node-in-a-bst/description/
文档讲解:https://programmercarl.com/0450.%E5%88%A0%E9%99%A4%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html
状态:需二刷,确定删除节点的逻辑耗费很长时间

思路:由于删除的节点可能是根节点,因此需要一个dummy节点指向root

  1. 寻找待删除的节点target及其父节点father
    • 注意:二叉树中可能不存在待删除的节点,这种情况直接返回root
  2. 寻找替换节点
    • 如果左子树存在,寻找左子树中的最大值cur及其父节点last
      • cur为target左儿子:cur.right = target.right,father->cur
      • cur为target左子树中的某个节点(右子树为空,左子树未必)
        • 删除cur节点:last.right = cur.left
        • 删除target节点:cur.left = target.left,cur.right = target.right,father->cur
    • 反之,如果右子树存在,寻找右子树中的最小值cur及其父节点last,类比左子树操作
    • 如果左右子树均不存在,则直接删除father指向target的指针
  3. 返回dummy.left

时间复杂度: O ( l o g N ) O(logN) O(logN);空间复杂度: O ( 1 ) O(1) O(1)

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        TreeNode dummy = new TreeNode(100001,root,null);
        TreeNode father = dummy, target = root;
        while(target != null && target.val != key){
            father = target;
            if(target.val > key)
                target = target.left;
            else
                target = target.right;
        }

        if(target == null)
            return root;

        if(target.left != null){
            TreeNode last = target;
            TreeNode cur = target.left;
            while(cur.right != null){
                last = cur;
                cur = cur.right;
            }

            if(last == target){
                cur.right = target.right;
            }else{
                last.right = cur.left;
                cur.left = target.left;
                cur.right = target.right;
            }

            if(father.left == target)
                father.left = cur;
            else
                father.right = cur;
        }else if(target.right != null){
            TreeNode last = target;
            TreeNode cur = target.right;
            while(cur.left != null){
                last = cur;
                cur = cur.left;
            }

            if(last != target){
                last.left = cur.right;
                cur.left = target.left;
                cur.right = target.right;
            }

            if(father.left == target)
                father.left = cur;
            else
                father.right = cur;
        }else{
            if(father.left == target)
                father.left = null;
            else
                father.right = null;
        }

        return dummy.left;
    }
}

标签:right,target,val,root,cur,二叉,搜索,树中,left
From: https://blog.csdn.net/m0_45175414/article/details/145115450

相关文章

  • C++搜索问题
    C++中的搜索算法是指在数据结构或图中寻找某些特定元素或满足条件的路径的算法。搜索算法广泛应用于问题求解、路径规划、数据检索等领域。常见的搜索算法可以分为两大类:无权搜索算法:如深度优先搜索(DFS)、广度优先搜索(BFS)。启发式搜索算法:如A算法、双向搜索、IDA算法等。1.......
  • 代码审计-PHP原生开发&SQL注入&数据库监控&正则搜索&文件定位&静态分析
    知识点1、PHP审计-原生态开发-SQL注入&数据库语句监控2、PHP审计-原生态开发-SQL注入&正则匹配搜索3、PHP审计-原生态开发-SQL注入&功能追踪代码审计分类:1、原生态开发-代码审计源码案例2、框架类开发-代码审计源码案例3、组件类开发-代码审计源码案例4、前端类开发-代码......
  • 和 google 搜索引擎“交个朋友”
    在前前公司,有一个哥们,解决问题的速度贼快,他总能快速的在浏览器中搜索到他想要的答案。虽然我们遇到的相同的问题,但是搜索出来的答案,却总是千差万别,甚至尝试各种描述都得不到他搜索的结果,当时真是百思不得其解。对于搜索不到他那样的答案,到底是哪个环节出现了问题?直到若干年后,......
  • 代码随想录:验证二叉搜索树
    二叉搜索树的中序遍历结果是一个递增的数组为了省空间可以用一个变量记录上一次的数字我一开始设置上一次的为null,结果c++中int为null时实际为0,所以要用最小值/***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*......
  • 搜索与图论(二)-最短路问题(dijkstra、Bellman-Ford、SPFA、Floyd)
    目录一、单源最短路问题 1.朴素dijkstra算法O(n²) 2.堆优化Dijkstra算法O(mlogn)3.Bellman-Ford算法O(nm)4.SPFA算法 O(m)/O(nm)应用-判断负环 二、多元最短路问题O(n³)Floyd算法 一、单源最短路问题 问题定义:1.朴素dijkstra算法O(n²)适用于......
  • 【LeetCode 刷题】二分搜索
    此博客作为《代码随想录》的学习笔记,主要内容为二分搜索法及相关题目解析。文章目录704.二分查找35.搜索插入位置34.在排序数组中查找元素的第一个和最后一个位置69.x的平方根367.有效的完全平方数以下所有二分法算法均基于左闭右闭区间704.二分查找LeetCode......
  • 数据结构—《二叉树的定义与特性》
    目录1.二叉树的定义2.特殊的二叉树1)满二叉树2)完全二叉树3)二叉排序树。4)平衡二又树。5)正则二文树3.二叉树的性质4.二叉树的存储结构1)顺序存储结构2)链式存储结构1.二叉树的定义二叉树是一种特殊的树形结构,其特点是每个结点至多只有两棵子树(即二叉树中不存在度大......
  • 数据结构之链式二叉树
    前言:前面我们学习了树相关的概念及堆的实现,今天来看看二叉树的实现。正式实现二叉树前,我们先了解一些基础知识。对于二叉树基础知识不清楚的可以观看数据结构------树这篇文章,回顾一下知识,有助于理解二叉树。二叉树的遍历方式都有哪些呢?.前序遍历:按照根节点,左节点,右节......
  • 代码随想录:最大二叉树
    白送/***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode():val(0),left(nullptr),right(nullptr){}*TreeNode(intx):val(x),left(nullptr),right(nullptr){}......
  • 代码随想录:从中序与后序遍历序列构造二叉树
    /**Definitionforabinarytreenode.structTreeNode{intval;TreeNode*left;TreeNode*right;TreeNode():val(0),left(nullptr),right(nullptr){}TreeNode(intx):val(x),left(nullptr),right(nullptr){}TreeNode(intx,TreeNo......