• 刷题DAY22 | LeetCode 235-二叉搜索树的最近公共祖先 701-二叉搜索树中的插入操作 450-删除二叉搜索树中的节点


    235 二叉搜索树的最近公共祖先(medium)

    给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

    百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

    例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

    思路:利用BST的性质,递归或者迭代均可

    代码实现1(递归):

    class Solution {
    public:
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    代码实现2(迭代):

    class Solution {
    public:
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            while(root) {
                if (root->val > p->val && root->val > q->val) {
                    root = root->left;
                } else if (root->val < p->val && root->val < q->val) {
                    root = root->right;
                } else return root;
            }
            return NULL;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    详细解析:
    思路视频
    代码实现文章


    701 二叉搜索树中的插入操作(medium)

    给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

    注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

    思路:迭代or递归均可

    代码实现1(递归):

    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;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    代码实现2(迭代):

    class Solution {
    public:
        TreeNode* insertIntoBST(TreeNode* root, int val) {
            if (root == NULL) {
                TreeNode* node = new TreeNode(val);
                return node;
            }
            TreeNode* cur = root;
            TreeNode* parent = root; // 这个很重要,需要记录上一个节点,否则无法赋值新节点
            while (cur != NULL) {
                parent = cur;
                if (cur->val > val) cur = cur->left;
                else cur = cur->right;
            }
            TreeNode* node = new TreeNode(val);
            if (val < parent->val) parent->left = node;// 此时是用parent节点的进行赋值
            else parent->right = node;
            return root;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    详细解析:
    思路视频
    代码实现文章


    450 删除二叉搜索树中的节点(medium)

    给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

    一般来说,删除节点可分为两个步骤:

    首先找到需要删除的节点;
    如果找到了,删除它。

    思路:分好情况递归实现即可,注意对删除节点内存的释放

    代码实现:

    class Solution {
    public:
        TreeNode* deleteNode(TreeNode* root, int key) {
            if (root == nullptr) return root; // 第一种情况:没找到删除的节点,遍历到空节点直接返回了
            if (root->val == key) {
                // 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
                if (root->left == nullptr && root->right == nullptr) {
                    ///! 内存释放
                    delete root;
                    return nullptr;
                }
                // 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
                else if (root->left == nullptr) {
                    auto retNode = root->right;
                    ///! 内存释放
                    delete root;
                    return retNode;
                }
                // 第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
                else if (root->right == nullptr) {
                    auto retNode = root->left;
                    ///! 内存释放
                    delete root;
                    return retNode;
                }
                // 第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
                // 并返回删除节点右孩子为新的根节点。
                else {
                    TreeNode* cur = root->right; // 找右子树最左面的节点
                    while(cur->left != nullptr) {
                        cur = cur->left;
                    }
                    cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置
                    TreeNode* tmp = root;   // 把root节点保存一下,下面来删除
                    root = root->right;     // 返回旧root的右孩子作为新root
                    delete tmp;             // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)
                    return root;
                }
            }
            if (root->val > key) root->left = deleteNode(root->left, key);
            if (root->val < key) root->right = deleteNode(root->right, key);
            return root;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    详细解析:
    思路视频
    代码实现文章

  • 相关阅读:
    CBAM注意力机制详解(附pytorch复现)
    将mqtt的消息存储至mysql数据库
    【C++】双指针算法:和为s的两个数字
    Maven学习笔记
    docker-compose 搭建 kafka 集群
    2024-3-13-C++day3作业
    关键词排名我们如何才能优化到首页
    @Async注解失效及原理
    互联网电视流氓乱收费被市场惩罚,传统品牌合力挤压互联网电视
    序列查询 CSP202112-1
  • 原文地址:https://blog.csdn.net/wangs29/article/details/136682898