代码随想录算法训练营第二十天(二叉树 七)

day19 周日放假 今天依旧是二叉树环节

力扣题部分:

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

题目链接:. - 力扣(LeetCode)

题面:

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

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

思路:

        和day18的二叉树公共祖先不同的是,这一次我们可以利用二叉搜索树的特点遍历一个路径就够了,其他的倒没什么太大区别。

具体思路细节内容可以看day18的最后一题 236. 二叉树的最近公共祖先,这里就不重复了。

传送门(day18):代码随想录算法训练营第十八天(二叉树 六)-CSDN博客

代码实现:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(p -> val > q -> val) swap(q, p);
        if(root -> val >= p -> val && root  -> val <= q -> val) return root;
        if(root -> val < p -> val && root -> right) return lowestCommonAncestor(root -> right, p, q);
        if(root -> val > q -> val && root -> left) return lowestCommonAncestor(root -> left, p, q);
        return nullptr;
    }
};

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

题目链接:. - 力扣(LeetCode)

题面:

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

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

思路:

        按照最简单的想法,一条路径走到底最后创造一个叶子节点挂树上就好了,可以不重构二叉树就不要重构二叉树了,不然就很麻烦(就像下一道题)。

代码实现:

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(!root)
        {
            TreeNode* newnode = new TreeNode(val);
            return newnode;
        }
        if(root -> val > val) root -> left = insertIntoBST(root -> left, val);
        if(root -> val < val) root -> right = insertIntoBST(root -> right, val);
        return root;
    }
};

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

题目链接:. - 力扣(LeetCode)

题面:

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

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

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

思路:

        我们知道插入可以插入在叶子节点也可以不插入在叶子节点,而删除就没得选择,所有情况都要考虑,那就得按需要删除的结点情况分类讨论了:

1.没找到。

        解决办法:遍历到空节点直接返回。

2.找到了,在叶子节点上。

        解决办法:删除节点并返回空节点。

3.找到了,左边有子树右边没有。

        解决办法:像链表一样,要删除的节点的父节点指向要删除节点的左节点,相当于绕过要删除的节点,然后记得删除释放空间。

4.找到了,右边右子树左边没有。

        解决办法:第三条类似,父节点指向删除节点的右节点。

5.找到了,左右两边都有子树。

        解决办法:最难的部分。先讲操作:将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点

我们知道二叉搜索树要保证中序遍历递增,删除节点的左子树全部比右子树小,该节点一删右节点像之前一样一补上去,整个左子树就悬空了,由于左子树都比右子树小,所以只能把悬空的左子树根节点放在右节点最小的节点左侧,这样就可以让中序遍历仍旧是递增的了。(如果还有点懵,可以尝试画个图自己手动删除节点理解一下)

代码实现:

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (root == nullptr) return root; // 第一种情况
        if (root->val == key) {
            // 第二种情况
            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;
                TreeNode* tmp = root;
                root = root->right;
                delete tmp;
                return root;
            }
        }
        if (root->val > key) root->left = deleteNode(root->left, key);
        if (root->val < key) root->right = deleteNode(root->right, key);
        return root;
    }
};

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值