Day22~235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

57 阅读3分钟

摘要

本文主要介绍了LeetCode二叉树的几个题目,包括235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点。

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

1.1 思路

  • 递归遍历,利用二叉搜索树是有序的
  • 递归终止:root为null,p, q分别在root的左右两边
  • 递归过程:如果p, q都小于root遍历左子树;如果p, q都大于root遍历右子树;如果root=p或root=q则返回root

1.2 代码

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) {
            return null;
        }
        if(root.val > p.val && root.val < q.val) {
            return root;
        }
        if(root.val < p.val && root.val > q.val) {
            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;
        }
    }

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

2.1 思路

  • 二叉搜索树中插入任何一个节点都可以二叉树的节点中找到它的位置,所以不需要调整二叉树的结构,只需要遍历二叉树找到空节点即可

1、测试用例:root = [5,null,14,10,77,null,null,null,95,null,null];val = 4

二叉搜索树中插入任何一个节点都可以二叉树的节点中找到它的位置,不一定是二叉树的叶子节点

2、测试用例:root = [];val = 5

当节点为空时,不应该返回空;将 val 构造新节点并返回

2.2 代码

    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) {
            TreeNode node = new TreeNode(val);
            return node;
        }
        
        doInsertIntoBST(root, val);
        return root;
    }
​
    public void doInsertIntoBST(TreeNode root, int val) {
        if(val > root.val) {
            if(root.right == null) {
                TreeNode node = new TreeNode(val);
                root.right = node;
                return;
            }
            insertIntoBST(root.right, val);
        } else {
            if(root.left == null) {
                TreeNode node = new TreeNode(val);
                root.left = node;
                return;
            }
            insertIntoBST(root.left, val);
        }
    }

优化版:代码随想录-二叉搜索树中的插入操作-其他语言版本-Java

    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
            return new TreeNode(val);
            
        if (root.val < val){
            root.right = insertIntoBST(root.right, val); // 递归创建右子树
        }else if (root.val > val){
            root.left = insertIntoBST(root.left, val); // 递归创建左子树
        }
        return root;
    }

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

3.1 思路

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

  • 递归遍历,找到相应的节点并删除

  • 分为五种情况

    1. 没找到删除的节点

    2. 删除的节点是叶子节点,左为空,右为空

    3. 删除的节点左不空,右为空

      • 父节点直接指向左节点
    4. 删除的节点左为空,右不空

      • 父节点直接指向右节点
    5. 删除的节点左不空,右不空

      1. 找右子树最左面的节点
      2. 把要删除的节点(root)左子树放在cur的左孩子的位置
      3. 返回旧root的右孩子作为新root

3.2 代码

    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null) {
            return null;
        }
​
        if(key > root.val) {
            root.right = deleteNode(root.right, key);
        } else if(key < root.val) {
            root.left = deleteNode(root.left, key);
        } else {
            if(root.left == null && root.right == null) {
                return null;
            } else if(root.left != null && root.right == null) {
                return root.left;
            } else if(root.left == null && root.right != null) {
                return root.right;
            } else {
                // 1.找右子树最左面的节点
                TreeNode cur = root.right;
                while(cur.left != null) {
                    cur = cur.left;
                }
                // 2.把要删除的节点(root)左子树放在cur的左孩子的位置
                cur.left = root.left;
                // 3.返回旧root的右孩子作为新root
                return root.right;
            }
        }
        return root;
    }

参考资料

代码随想录-二叉搜索树的最近公共祖先

代码随想录-二叉搜索树中的插入操作

代码随想录-删除二叉搜索树中的节点