当前位置: 首页 > article >正文

算法训练(leetcode)二刷第十七天 | 235. 二叉搜索树的最近公共祖先、701. 二叉搜索树中的插入操作、*450. 删除二叉搜索树中的节点

刷题记录

  • 235. 二叉搜索树的最近公共祖先
  • 701. 二叉搜索树中的插入操作
    • 递归
    • 迭代一
    • 迭代二
  • 450. 删除二叉搜索树中的节点
    • 思路一

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

leetcode题目地址

二叉搜索树比普通树更容易搜索,因为其具有左小右大的性质。

时间复杂度: O ( H ) O(H) O(H)
空间复杂度: O ( n ) O(n) O(n)

// java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {

    public TreeNode findAncestor(TreeNode root, TreeNode p, TreeNode q){
        if(root == null) return root;
        // 比较大值大 向左走
        if(root.val > q.val){
            TreeNode left = findAncestor(root.left, p, q);
            if(left != null) return left;
        }
        // 比较小值小 向右走
        if(root.val < p.val) {
            TreeNode right = findAncestor(root.right, p, q);
            if(right != null) return right;
        }
        // 当前节点处于二者中间 即为最近公共祖先
        return root;

    }

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(p.val > q.val){
            TreeNode temp = p;
            p = q;
            q = temp;
        }
        return findAncestor(root, p, q);
    }
}

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

leetcode题目地址

利用二叉搜索树性质插入。

时间复杂度: O ( H ) O(H) O(H)
空间复杂度: O ( n ) O(n) O(n)

递归

// java
/**
 * 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 void insert(TreeNode root, int val){
        if(root == null) return;
        if(val > root.val && root.right == null){
            root.right = new TreeNode(val);
            return;
        }
        if(val < root.val && root.left == null){
            root.left = new TreeNode(val);
            return;
        }
        if(val > root.val) insert(root.right, val);
        if(val < root.val) insert(root.left, val);
    }

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

迭代一

// java
/**
 * 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) return new TreeNode(val);
        TreeNode cur = root;
        TreeNode parent = root;
        while(cur != null){
            parent = cur;
            if(cur.val > val) cur = cur.left;
            else cur = cur.right;
        }
        cur = new TreeNode(val);
        if(val > parent.val) parent.right = cur;
        else parent.left = cur;
        return root;
    }
}

迭代二

// java
/**
 * 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) return new TreeNode(val);
        TreeNode cur = root;
        while(true){
            if(cur.val > val) {
                if(cur.left == null) {
                    cur.left = new TreeNode(val);
                    break;
                }
                cur = cur.left;
            } else {
                if(cur.right == null){
                    cur.right = new TreeNode(val);
                    break;
                }
                cur = cur.right;
            }
        }
        return root;
    }
}

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

leetcode题目地址

思路一

使用二叉搜索树的删除操作在数据结构中的解题思路:

  1. 若要删除的结点左右子树均为空,则直接删除。
  2. 若要删除结点左子树为空右子树不空,则用右子树的最左结点替换当前要删除结点,然后递归删除右子树的最左节点。
  3. 若要删除结点左子树不空右子树为空,则用左子树的最右结点替换当前要删除结点,然后递归删除左子树的最右节点。
  4. 若要删除结点的左右子树均不为空,则按照2、3中的任一规则进行删除。

也就是说,只有递归到叶节点(左右子树均空)才会物理删除结点,有孩子时只会对值进行替换,然后继续递归。

依照上述思路,代码如下:

时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( l o g n ) O(logn) O(logn)

// java
/**
 * 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 {
	// 标识根节点
    boolean flag;
    // cur: 要删除的结点  parent:cur的父节点
    public void delete(TreeNode cur, TreeNode parent){
        // 叶子节点
        if(cur.left == null && cur.right == null){
            // 根节点
            if(parent == null) {
                this.flag = true;
                return;
            }
            // 是父节点的左子树则将左子树置空
            if(parent.left == cur) parent.left = null;
            // 反之,置空右子树
            else parent.right = null;
            
        }else if(cur.left == null){
            // 左空右不空 取右子树最左节点
            TreeNode node = cur.right;
            TreeNode nodeParent = cur;
            while(node.left != null){
                nodeParent = node;
                node = node.left;
            }
            cur.val = node.val;
            delete(node, nodeParent);
            
        } else{
            // 右空左不空/左右都不空  取左子树最右节点
            TreeNode node = cur.left;
            TreeNode nodeParent = cur;
            while(node.right != null){
                nodeParent = node;
                node = node.right;
            }
            cur.val = node.val;
            delete(node, nodeParent);
        }
    }
    public TreeNode deleteNode(TreeNode root, int key) {
        TreeNode cur = root;
        TreeNode parent = null;
        // 利用搜索树性质查找要删除结点
        while(cur != null && cur.val != key){
            parent = cur;
            if(key > cur.val) cur = cur.right;
            else cur = cur.left;
        }
        
        // 找到
        if(cur!=null){
            // 标记树中只有一个节点且要删除的就是根节点
            this.flag = false;
            delete(cur, parent);
            // 要删除的是根且树中仅有根这一个节点,则将根节点置空
            if(this.flag) root = null;
        }
        return root;
    }
}

http://www.kler.cn/a/387293.html

相关文章:

  • window下安装rust 及 vscode配置
  • Linux下MySQL的简单使用
  • WPF 应用程序中使用 Prism 框架时,有多种方式可以注册服务和依赖项
  • 实现3D热力图
  • Android HandlerThread 基础
  • 3.2 软件需求:面对过程分析模型
  • 停车场微信小程序的设计与实现(lw+演示+源码+运行)
  • 饱和限幅器MATLAB和CODESYS平台下的实现
  • 同步时钟装置为新能源电力赋能强基!
  • 【数据集】【YOLO】【目标检测】水面船只识别数据集 9798 张,YOLO船只识别算法实战训练教程!
  • [FBCTF 2019]rceservice 详细题解
  • O-RAN 分布式单元 (O-DU) 参考架构
  • 【SPIE出版 | ISSN: 0277-786X,EI检索稳定!】2024年计算机视觉与图像处理国际学术会议 (CVIP 2024,11月15-17日)
  • 以旅游产品为例改写一篇系统架构风格的论文
  • Docker Compose部署Rabbitmq(延迟插件已下载)
  • 搜维尔科技:Manus VR数据手套-人形机器人的远程操作和机器学习
  • 从0开始学习机器学习--Day20--优化算法的思路
  • leetcode25:k个一组链表反转
  • C++STL容器详解——list
  • nvidia本地环境部署以及jetson交叉编译环境部署
  • 网络安全技术及其在企业中的应用
  • Jest进阶知识:深入测试 React Hooks-确保自定义逻辑的可靠性
  • yum下载时出现报错 Couldn‘t read a file:// file for file:///mnt/repodata/repomd.xml
  • 进程设计理念
  • 【sass】sass中两种去重的方法:混合 - mixin/include、继承 - extend
  • 【热门主题】000039 物联网智能项目:开启智慧未来新篇章