235. 二叉搜索树的最近公共祖先
题目链接:235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)
文章链接:代码随想录 (programmercarl.com)
视频链接:二叉搜索树找祖先就有点不一样了!| 235. 二叉搜索树的最近公共祖先
这道题与Day21做的找二叉树的最近公共祖先类似,但多出了一个条件,指定为二叉搜索树,那么我们就可以通过二叉搜索树的性质来寻找最近公共祖先了。
如果是普通二叉树,我们需要从底层开始遍历,所以要用到后续递归,但这道题由于二叉搜索树的特殊性,任何递归顺序都可以。
二叉搜索树定义:一个节点的左子树上的元素一定小于父节点的元素,右子树上的元素一定大于父节点上的元素。
所以只要我们通过前序递归,找到第一个在p和q之间的节点,假如p<q,它就代表着它的左子树上一定有一个节点p,右字数上一定有一个节点q,它就一定是最近的公共祖先,我如果往左边继续递归,会错过q,往右边递归,就会错过p。
代码如下:
lass Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL) return NULL;
if((root->val>=p->val&&root->val<=q->val)||(root->val>=q->val&&root->val<=p->val)) return root;//找到在p和q之间的节点
TreeNode*left=lowestCommonAncestor(root->left,p,q);
TreeNode*right=lowestCommonAncestor(root->right,p,q);
if(left!=NULL&&right!=NULL) return root;
else if(left!=NULL&&right==NULL) return left;
else if(left==NULL&&right!=NULL) return right;
else return NULL;
}
};
701.二叉搜索树中的插入操作
题目链接:701. 二叉搜索树中的插入操作 - 力扣(LeetCode)
文章链接:代码随想录 (programmercarl.com)
视频链接:原来这么简单? | LeetCode:701.二叉搜索树中的插入操作
这道题看起来花里胡哨的,其实难度并不大,不管是什么数字,我都可以在叶子节点插入。那么这道题思路就很简单了,就通过递归比较,root->val和value值的大小,如果root->val大于value,那么就递归到root的左节点,如果root->val小于value,那么久递归到root的有节点。
直到递归到root==NULL时,这就意味着已经递归到最底部了,通过创建一个新的节点插入就好了。代码如下:
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.删除二叉搜索树中的节点
题目链接:450. 删除二叉搜索树中的节点 - 力扣(LeetCode)
文章链接:代码随想录 (programmercarl.com)
视频链接:调整二叉树的结构最难!| LeetCode:450.删除二叉搜索树中的节点
这道题其实对于算法啥的没有多少要求,主要难在对情况的考虑以及处理。这里要分五种情况。
第一种情况:二叉搜索树中根本没有这样的节点。
第二种情况:找得到节点,且是叶子节点,
第三种情况:找得到节点,有左孩子没右孩子。
第四种情况:找得到节点,没右孩子有右孩子。
第五种情况:找得到节点,左右孩子都有。
代码如下:
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)//第三种情况,有左孩子没右孩子
{
TreeNode* cur=root->left;
delete root;
return cur;
}
else if(root->left==NULL&&root->right!=NULL)//第四种情况,没左孩子有右孩子
{
TreeNode* cur=root->right;
delete root;
return cur;
}
else//第五种情况,左右孩子都有
{
TreeNode* asd=root->right;
while(asd->left!=NULL)//通过循环找到root的右子树中最小的节点
{
asd=asd->left;
}
asd->left=root->left;
TreeNode* cur=root->right;
delete root;
return cur;
}
}
if(root->val>key) root->left=deleteNode(root->left,key);
if(root->val<key) root->right=deleteNode(root->right,key);
return root;
}
};
还需要注意的是,C++中删除节点,还需要有delete的好习惯!
Day22 打卡成功,对二叉搜索树的进一步理解与应用,耗时2.5小时,再接再厉。