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

题目链接:235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

作者思考: 

本题也是求最近的公共祖先,那么这题和之前那个求公共祖先的题目有什么区别呢?本题给我们的二叉树是搜索二叉树,也就是这个二叉树是一个有序二叉树。当题目给我们这种信息,我们一定要利用好二叉搜索树的特性。

因为是有序树,所以 如果 中间结点 是 q 和 p的公共祖先,那么中结点的数组一定在[p,q]区间。即中结点 > p && 中结点 < q 或者 中结点 > q && 中结点 < p。

那么只要从上到下遍历,遇到的结点数值在[p,q]或者[q,p]区间中 则一定可以说明该结点就是q和p的公共祖先。

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

 由上图可以看出,第一个在[p,q]或者[q,p]区间中结点 一定是最近结点,如果再向下遍历 要么p结点不在范围内,要么q结点不在范围内。

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

题目链接: 701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

作者思考:

本题是在二叉搜索树中进行插入,且二叉搜索树又是有序的。那么我们只需要将待插入元素在树中进行比较,根据二叉搜素树的特性就能找到适合的插入位置。代码随想录算法训练营第22天 | LeetCode.235.二叉搜索树的最近公共祖先、LeetCode.701.二叉搜索树中的插入操作、LeetCode.450删除二叉搜索树中的节点_第2张图片

 

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) {
            //当结点为空的时候 就是找到了插入点
            TreeNode node = new TreeNode(val);
            return node;
        }
        //当前结点的值 与目标值进行比较
        //当大于目标值的时候 就向左子树遍历
        if (root.val > val) {
            root.left = insertIntoBST(root.left, val);
        }
        //当小于目标值的时候 就向右子树遍历
        if (root.val < val) {
            root.right = insertIntoBST(root.right, val);
        }
        return root;
    }
}

题目链接: 450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

作者思考: 

本题是删除在二叉搜索树中的节点。和上一题的添加结点不同,上一题的添加结点操作都是在叶子结点上,我们不需要更改原本二叉树的结构。但是本题删除二叉搜索树的结点,可能会删除非叶子结点,那意味着要更改二叉树的结构。

本题一共有五种情况:

1.没找到删除点

2.删除点 左右孩子为空

3.删除点 左孩子不为空 右孩子为空

4.删除点 左孩子为空 右孩子不为空

5.删除点左右孩子都不为空

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        //五种情况
        //1.没找到删除点
        if (root == null) {
            return root;
        }
        if (root.val == key) {
            //2.删除点 左右孩子为空
            if (root.left == null && root.right == null) {
                return null;
            }else if (root.left != null && root.right == null) {
            //3.删除点 左孩子不为空 右孩子为空
                return root.left;
            }else if (root.left == null && root.right != null) {
            //4.删除点 左孩子为空 右孩子不为空
                return root.right;
            }else {
            //5.删除点左右孩子都不为空
                TreeNode cur = root.right;//将删除点的右子树 赋值给 cur
                while (cur.left != null) {//寻找删除点的右子树中 值大于删除点的最小值
                    cur = cur.left;
            }
            cur.left = root.left;//将删除点的左子树 指向 cur.left
            return root.right;
            }
        }

        root.left = deleteNode(root.left, key);
        root.right = deleteNode(root.right, key);
        return root;
    }
}

你可能感兴趣的:(算法,c++,leetcode)