一、LeetCode235. 二叉搜索树的最近公共祖先
状态:已解决
1.思路
此题与上题有所不同,此题求的是二叉搜索树的最近公共祖先,另一题求的是普通二叉树的最近公共祖先,我们知道二叉搜索树是一棵有序树,这意味着当一个节点大于p、q中的最小值,小于p、q中的最大值时,这个节点就将p、q分到了不同子树。那么这个节点一定是最近的公共祖先节点吗?请看图:
假如p为0,q为5,值介于0和5之间的节点有2、4,很明显2才是最近公共祖先,4虽然也将0、5分到了不同树中,但并不是公共节点。那怎样的节点才是公共节点呢?第一个满足值在[p,q]之间的节点。(注:是闭区间,因为p,q本身都能作为公共节点,另外这里的[p,q]是假设p为较小值)
假设第一个满足节点为t
(1)t上面的节点:因为t是第一个满足值在[p,q]内的节点,那么t上面的节点要么小于p,要么大于q,不能将二者划到两棵子树中,也就不可能是最近的。
(2)t下面的节点:t下面的节点虽然也可能满足值在[p,q],但可能不是p、q的公共节点,要么刚好在p所在的子树,要么刚好在q所在的子树(不包含子树根节点)
综上,只有第一个满足值在[p,q]之间的节点才是最近公共节点。
2.代码实现
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL) return NULL;
if(root->val <= max(p->val,q->val) && root->val >= min(p->val,q->val)){
return root;
}
TreeNode* result = nullptr;
if(root->val > max(p->val,q->val)){
result = lowestCommonAncestor(root->left,p,q);
}else{
result = lowestCommonAncestor(root->right,p,q);
}
return result;
}
};
二、701.二叉搜索树中的插入操作
题目链接/文章讲解/视频讲解: https://programmercarl.com/0701.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%8F%92%E5%85%A5%E6%93%8D%E4%BD%9C.html状态:已解决
1.思路
因为这道题没有要求插入之后的二叉搜索树必须是一颗平衡二叉树,因此,只要按照二叉搜索树的规则去遍历,遇到空节点就插入节点就可以了。
如:插入元素10 ,需要找到末尾节点插入便可,一样的道理来插入元素15,插入元素0,插入元素6,并不需要调整二叉树的结构。
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);
}
else{
root->right = insertIntoBST(root->right,val);
}
return root;
}
};
三、 450.删除二叉搜索树中的节点
题目链接/文章讲解/视频讲解: https://programmercarl.com/0450.%E5%88%A0%E9%99%A4%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html状态:已解决
1.思路
找到的节点可能有五种情况:
(1)左右孩子都为空:直接删除节点,返回NULL。
(2)左孩子为空,右孩子不为空:返回右孩子。
(3)左孩子不为空,右孩子为空:返回左孩子。
(4)左右孩子都不为空:选择某个孩子为返回节点,然后将另一个孩子嫁接到被选中孩子的最下面。如图:
除了找到待删节点外,还有一种情况,就是遍历完叶子节点后都还没找到待删节点,那么直接返回NULL。
2.代码实现
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root == NULL) return NULL;
if(root->val == key){
if(root->left == NULL && root->right == NULL){
delete root;
return NULL;
}
else if(root->left == NULL && root->right != NULL) return root->right;
else if(root->left != NULL && root->right == NULL) return root->left;
else{
TreeNode * node = root;
while(node->right){
node = node->right;
}
node->right = root->right;
return root->left;
}
}
if(root->val > key){
root->left = deleteNode(root->left,val);
}
else{
root->right = deleteNode(root->right,val);
}
return root;
}
};