第一次遇到没做出来,看答案也不理解的题。好在我觉得这题没什么价值,这样繁琐的题,在面试的时候应该只会考个思路。思路不难想。
2201的ppt都说“太长了”,想必我也不太需要掌握吧!
算法:当遇到第一个在p,q之间(包括p,q,因为root可能是p或q本身)的数的node就是我们要找的node!剩下的根据形状调整指向就好。(很巧妙啊!)
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return nullptr;
if((p->val <= root->val && root->val <= q->val) || (q->val <= root->val && root->val <= p->val)) return root;
if(root->val > max(p->val, q->val)){
return lowestCommonAncestor(root->left, p, q);
}else if(root->val < max(p->val, q->val)){
return lowestCommonAncestor(root->right, p, q);
}
return nullptr;
}
};
不难,但第一次交没过。
class Solution {
private:
void helper(TreeNode* root, int val){
if(!root) return;
if(root->val < val){
if(!root->right){
root->right = new TreeNode(val);
return;
}
helper(root->right, val);
}else{
if(!root->left){
root->left = new TreeNode(val);
return;
}
helper(root->left, val);
}
}
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(!root) return new TreeNode(val);
helper(root, val);
return root;
}
};
3.Delete Node in a BST (没做出来)
- Delete leaf node: easy!
- Delete node with one child: easy!
- Delete node with two children: find the next largest, then replace it on (if the second largest also have a right child, (since it can only have right child) attach them to the replaced node’s right node’s left child).
画了一部分时间,没做出来,放弃了。把放弃之前的代码和思路摆上去吧。
****** THIS IS INCORRECT!!!!!!!! ******
class Solution {
private:
TreeNode* prev = nullptr;
TreeNode* findSucc(TreeNode* root){
while(root->left){
root = root->left;
}
return root;
}
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return root;
if(root->val == key){
if(!root->left && !root->right){
delete root;
return nullptr;
}else if(!root->left || !root->right){
if(!root->left){
prev->right = root->right;
delete root;
return prev->right;
}else{
prev->left = root->left;
delete root;
return prev->left;
}
}else{
TreeNode* tmp = findSucc(root->right); //second largest
if(tmp->right){
root->right->left = tmp->right;
}
if(prev->left == root){
delete prev->left;
prev->left = tmp;
}else{
delete prev->right;
prev->right = tmp;
}
return tmp;
}
}
if(root->val > key) {prev = root; root->left = deleteNode(root->left, key);}
if(root->val < key) {prev = root; root->right = deleteNode(root->right, key);}
return root;
}
};
具体下面这段代码为什么能过,我一点都不理解。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (root == nullptr) return root;
if (root->val == key) {
if (root->right == nullptr) { // 这里第二次操作目标值:最终删除的作用
return root->left;
}
TreeNode *cur = root->right;
while (cur->left) {
cur = cur->left;
}
swap(root->val, cur->val); // 这里第一次操作目标值:交换目标值其右子树最左面节点。
}
root->left = deleteNode(root->left, key);
root->right = deleteNode(root->right, key);
return root;
}
};
后续:2023.2.10更新:
整理了一下心态,把这个题重写了一下,其实也没有那么难。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return root;
if(root->val == key){
if(!root->left && !root->right){ // leaf node
delete root;
return nullptr;
}else if(!root->left && root->right){ //missing only left
TreeNode* right = root->right;
delete root;
return right;
}else if(root->left && !root->right){ //missing only right
TreeNode* left = root->left;
delete root;
return left;
}else{ //missing both
TreeNode* tmp = root->right;
while(tmp->left != nullptr){
tmp = tmp->left;
}
tmp->left = root->left;
TreeNode* tmp2 = root;
root = root->right;
delete tmp2;
return root;
}
}
if(root->val > key) root->left = deleteNode(root->left, key);
if(root->val < key) root->right = deleteNode(root->right, key);
return root;
}
};
文章讨论了在二叉搜索树中查找最低公共祖先(LowestCommonAncestor)、插入新值以及删除节点的算法。对于LCA,提出了基于节点值的巧妙解决方案;插入操作通过递归实现;删除操作涉及不同情况的处理,包括叶子节点、单子节点和双子节点的情况。文章提到了作者在理解和实现这些操作时遇到的挑战以及解决方案。

被折叠的 条评论
为什么被折叠?



