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

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

题目

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

在这里插入图片描述
示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

解题思路

  • 这道题最重要的需要理解的点是:如果root节点的值在 p q 之间,那么该节点一定是 p q 的公共祖先
  • 使用二叉搜索树的特性,节点中序遍历是单调递增的。
  • 可以通过比较节点 p q 的值和root节点的值来判断是不是公共祖先
    • 如果root节点的值大于p q 的值,那么 p q 一定在root的左侧
    • 反之,在右侧
    • 如果root节点的值在 p q 中间,那么正好就是 p q 的公共祖先

代码

递归法

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {

        if (root->val > p->val && root->val > q->val) {
	    	// root节点的值比 p q 都大
            return lowestCommonAncestor(root->left, p, q);
        } else if (root->val < p->val && root->val < q->val) {
    		// root节点的值比 p q 都小
            return lowestCommonAncestor(root->right, p, q);
        } else return root;
    }
};

迭代法

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;
    }
};

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

题目

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

解题思路

  • 不需要按照题目的说明改变二叉树的结构,只需要添加在最后面即可
  • 这样思路就简单多了,比较大小,然后定位到比较的对象的left 或 right 为空就插入

请添加图片描述

代码

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
    	// 终止条件,如果root为空,说明找到待插入的位置了
        // 这里return实际上是return给待插入位置节点的父节点。
        // 比如上面例子中,插入0时返回给上一层递归层其实对应的是节点1
        if (root == NULL) return new TreeNode(val);

        // 左遍历,如果待插入值小,则向左遍历
        // 这里赋值的其实就是上面终止条件返回过来的节点
        if (val < root->val) root->left = insertIntoBST(root->left, val);
        // 同理,向右遍历
        if (val > root->val) root->right = insertIntoBST(root->right, val);
        // 最终返回root节点,
        return root;
    }
};

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

题目

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

在这里插入图片描述

解题思路

待删除的节点有以下几种情况:
如果目标节点大于当前节点值,则去右子树中删除;
如果目标节点小于当前节点值,则去左子树中删除;
如果目标节点就是当前节点,分为以下三种情况:

  1. 其无左子:其右子顶替其位置,删除了该节点;
  2. 其无右子:其左子顶替其位置,删除了该节点;
  3. 其左右子节点都有:其左子树转移到其右子树的最左节点的左子树上,然后右子树顶替其位置,由此删除了该节点。

请添加图片描述

代码

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
    	// 情况1
        if (root == nullptr)    return nullptr;
        if (key > root->val)    root->right = deleteNode(root->right, key);     // 去右子树删除
        else if (key < root->val)    root->left = deleteNode(root->left, key);  // 去左子树删除
        else { // root.val == key 找到待删除节点
        	if (!root->right)   return root->left; // 情况2,欲删除节点无右子
        	if (!root->left)   return root->right; // 情况1,欲删除节点无左子
        	// 情况3,欲删除节点左右子都有 
        	TreeNode *node = root->right; // 找到待删除节点的右子树最左侧的节点
        	while (node->left) node = node->left; //这里就找到了右子树最左侧节点
        	node->left = root->left; //将root的左子树,赋值给node节点的左节点
        	root = root->right; // 用root节点的右子树,替换root节点,即可删除该节点
		}
		return root;
    }
};
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值