一、题目打卡
1.1 二叉搜索树的最近公共祖先(借助答案的思路)
题目链接:. - 力扣(LeetCode)
cpp
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return root;
if(root->val > p->val && root->val > q->val){
TreeNode* left = lowestCommonAncestor(root->left,p,q);
if(left) return left;
}
if(root->val < p->val && root->val < q->val){
TreeNode* right = lowestCommonAncestor(root->right,p,q);
if(right) return right;
}
return root;
}
};
这个题目同样利用了二叉搜索树的特性,比较关键的一个点就是公共祖先一定在 p 和 q 的val 的中间,而由这一点去由上向下找到的第一个满足条件的祖先,肯定就是需要找到的那个,因为此时深度肯定是最大的,题目本身也利用的剪枝的特点。
1.2 二叉搜索树的插入操作
题目链接:. - 力扣(LeetCode)
cpp
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;
}
};
有一点受上一个题目的启发,理由二叉搜索树的特点来区分递归的条件,这个题目我感觉比较巧妙的是最终结束的条件,也就是结束时候的位置,其实就应该是这个节点应该存在的位置。
1.3 删除二叉搜索树的节点
题目链接:. - 力扣(LeetCode)
cpp
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return nullptr;
root->left = deleteNode(root->left,key);
root->right = deleteNode(root->right,key);
if(root->val == key){
if(!root->left && !root->right) return nullptr;
if(root->left || root->right){
if(root->left){
TreeNode* tmp = root->left;
while(tmp->right) tmp = tmp->right;
tmp->right = root->right;
TreeNode* res = root->left;
delete root;
return res;
}else{
TreeNode* tmp = root->right;
while(tmp->left) tmp = tmp->left; // 关键是理解这个过程
tmp->left = root->left;
// 这一步不能少
TreeNode* res = root->right;
delete root;
return res;
}
}
}
return root;
}
};
题目理解起来其实不是很复杂,主要是理解这个迭代的过程,
这个主要的就是要理解为什么要使用 while ,因为需要找到最后一个满足插入条件的位置,这样才能保证二叉搜索树的性质维持,感觉答案分的情况有点多,应该是那样更清晰吧。