Day22 BST LeetCode 450 701 235

60 阅读2分钟

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

心得

  • 套用之前的二叉树公共祖先能过,纠结了会相等的含义是指针等还是指向的值等,审好题,题目意思唯一且一定存在,利用值即可
  • 多分析不同情况,多思考

题解

  • 利用二叉树的有序性,考虑好最终最近公共祖先情况,三种情况,都大于则在右子树,都小于则在左子树,在此之间只能是公共祖先
// 递归
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root->val > p->val && root->val > q->val) {
            return lowestCommonAncestor(root->left, p, q);
        } else if (root->val < p->val && root->val < q->val) {
            return lowestCommonAncestor(root->right, p, q);
        } else return root;
    }
};
// 迭代
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        while (root != nullptr) {
            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 root;   
    }

};

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

心得

  • 考虑复杂情况,之间插入为叶子结点即可

题解

  • 熟悉二叉树if扫一边的套路,同时通过递归返回值来接住父子结点间关系
  • 若没有返回值,则需要辅助变量来记录
// 递归 
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (root == nullptr) {
            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;
    }
};
// 迭代
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (root == nullptr) {
            TreeNode* node = new TreeNode(val);
            return node;
        } 
        TreeNode* prev = root;
        TreeNode* cur = root;
        while (cur != nullptr) {
            prev = cur;
            if (cur->val > val) cur = cur->left;
            else if (cur->val < val) cur = cur->right;
        }
        cur = new TreeNode(val);
        if (prev->val > val) prev->left = cur;
        else prev->right = cur;
        return root;
    }
};

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

心得

  • 看到删除想到需要调整,原以为的调整只是替换前后父子结点位置即可,这样会导致结果非二叉树,未仔细审题

题解

  • 考虑5种删除位置的情况(没找到和找到对应左右子结点空或非空情况)进行判断,分别处理即可
  • 注意判断条件精简代码,显式指出空或者非空,细节容易犯错
  • 同时delete时注意该结点前后依赖关系,删除的是该结点
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (root == nullptr) return nullptr;
        if (root->val == key) {
            if (root->left == nullptr && root->right == nullptr) { // 叶子结点情况
                delete root;
                return nullptr;
            } else if (root->left == nullptr) { // 单个子结点情况
                auto retNode = root->right;
                delete root;
                return retNode;
            } else if (root->right == nullptr){ // 单个子结点情况
                auto retNode = root->left;
                delete root;
                return retNode;
            } else { 
                TreeNode* cur = root->right; // 双子结点情况,需要调整,左右均可
                while (cur->left != nullptr) {
                    cur = cur->left;
                }
                cur->left = root->left;
                TreeNode* tmp = root; // 这里删除的是之前的结点,注意该处下面的顺序
                root = root->right;
                delete tmp;
                return root;
            }
        }
        if (root->val > key) root->left = deleteNode(root->left, key); // 接住递归返回的值
        if (root->val < key) root->right = deleteNode(root->right, key);
        return root;
    }
};