代码随想录算法训练营第22天 | 235 701 450

235 cr to 代码随想录 从上向下去递归遍历,第一次遇到 cur节点是数值在[p, q]区间中,那么cur就是 p和q的最近公共祖先。

用层序遍历

//层序遍历 迭代
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        queue<TreeNode*> que;
        que.push(root);
        while (!que.empty()) {
            TreeNode* curr = que.front();
            que.pop();
            if (curr->val<=max(p->val, q->val) && curr->val>=min(p->val, q->val)) return curr;
            if (curr->left) que.push(curr->left);
            if (curr->right) que.push(curr->right);
        }
        return NULL;
    }
};

用递归(我自己写的)

//递归
class Solution {
    TreeNode* traversal(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root==NULL || (root->val<=max(p->val, q->val) && root->val>=min(p->val, q->val))) return root;
        TreeNode* left = traversal(root->left, p, q);
        TreeNode* right = traversal(root->right, p, q);
        if (!left) return right;
        return left;
    }
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        return traversal(root, p, q);
    }
};

看了代码随想录,简化版。简化是因为并不是左右节点都要递归。

//递归简化
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);
        }
        if (root->val<p->val && root->val<q->val) {
            return lowestCommonAncestor(root->right,p,q);
        }
        return root;
    }
};

701 根据BST的规则 遍历到空节点插入就好

递归如下

//递归
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if (!root) {
            TreeNode* insert_node = new TreeNode(val);
            return insert_node;
        }
        if (val>root->val) root->right = insertIntoBST(root->right, val);
        if (val<root->val) root->left = insertIntoBST(root->left, val);
        return root;
    }
};

迭代

//迭代
class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        TreeNode* curr = root;
        TreeNode* pre = NULL;
        while (curr) {
            if (val>curr->val) {
                pre = curr;
                curr = curr->right;
            }
            else if (val<curr->val) {
                pre = curr;
                curr = curr->left;
            }
        }
        TreeNode* insert_node = new TreeNode(val);
        if (root == nullptr) return insert_node;
        if (val>pre->val) {
            pre->right = insert_node;
        }
        else {
            pre->left = insert_node;
        }

        return root;
    }
};

450 很难很难 一定要耐心处理每一种情况

cr to 代码随想录 分析:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

迭代法,一定要把删除单独分一个function出来写 不然太容易出错了!!!

//迭代
class Solution {
    TreeNode* deleter (TreeNode* target) {
        if (!target->left && !target->right) return nullptr;
        if (!target->left) return target->right;
        if (!target->right) return target->left;
        TreeNode* tmp = target->right;
        while (tmp->left) {
            tmp = tmp->left;
        }
        tmp->left = target->left;
        target = target->right;
        return target;
    }
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        TreeNode* curr = root;
        TreeNode* pre=nullptr;
        while (curr!=nullptr) {
            if (curr->val == key) break;
            pre = curr;
            if (key < curr->val) curr=curr->left;
            else if (key > curr->val) curr=curr->right;
        }
        if (curr==nullptr) return root;
        if (pre == nullptr) {
            root = deleter(curr);
        }
        else if (pre->left == curr) {
            pre->left = deleter(curr);
        }
        else if (pre->right == curr) {
            pre->right = deleter(curr);
        }
        return root;
    }
};

递归法 我这边c++但没有删掉要删的节点 浪费内存 二刷的时候要记得删 第一遍先懂逻辑

//递归
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (!root) return root;
        if (root->val == key) {
            if(!root->left && !root->right) return nullptr;
            else if (!root->left) root = root->right;
            else if (!root->right) root = root->left;
            else {
                TreeNode* delete_node = root->right;
                while (delete_node->left) {
                    delete_node = delete_node->left;
                }
                delete_node->left = root->left;
                root = root->right;
            }
            
        }
        else if (root->val>key) root->left = deleteNode(root->left, key);
        else root->right = deleteNode(root->right, key);
        return root;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值