算法训练营Day22 第六章 二叉树part8

第一题: 235. 二叉搜索树的最近公共祖先 

        这道题与昨天的最后一题比较相似,但相比于上一题,这道题可以利用二叉搜索树的特性(左子树上的值都比该节点的小,右子树上的值都比该节点的大)。

①递归法:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //p,q都在root的左子树一侧
        if(root->val > p->val && root->val > q->val) 
            return lowestCommonAncestor(root->left, p, q);
        //p,q都在root的右子树一侧
        else if(root->val < p->val && root->val < q->val)
            return lowestCommonAncestor(root->right, p, q);
        //p,q分别在root的左右两侧
        else return root;
    }
};

②迭代法:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        while(root) {
            //p,q都在root的左子树一侧
            if(root->val > p->val && root->val > q->val) 
                root = root->left;
            //p,q都在root的右子树一侧
            else if(root->val < p->val && root->val < q->val)
                root = root->right;
            //p,q分别在root的左右两侧
            else return root;
        }
        return nullptr;
    }
};

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

        这道题同样应该想到运用二叉搜索树的特性来解题,并且可以发现,在叶子节点插入节点就可以满足题意。当插入值小于当前比较节点的值时,就向当前节点的左子树一侧遍历,反之则向右子树一侧遍历。

①递归法:

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(!root) {
            TreeNode* node = new TreeNode(val);
            return node;
        }
        if(root->val > val) {
            root->left = insertIntoBST(root->left, val);
        }
        else {
            root->right = insertIntoBST(root->right, val);
        }
        return root;
    }
};

②迭代法:

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
        TreeNode* cur = root;
        if(!cur) {
            TreeNode* node = new TreeNode(val);
            return node;
        }
        TreeNode* prev = nullptr;
        while(cur) {
            prev = cur;
            if(cur->val > val) cur = cur->left;
            else cur = cur->right;
        }
        TreeNode* node = new TreeNode(val);
        if(prev->val > val) prev->left = node;
        else prev->right = node;
        return root;
    }
};

第三题: 450.删除二叉搜索树中的节点

        这道题要考虑以下五种情况:①没找到需要删除的节点;②要删除的节点为叶子节点;③要删除的节点左孩子为空,右孩子不为空;④要删除的节点左孩子不为空,右孩子为空;⑤要删除的节点左右孩子都不为空。

        对于情况①而言,相当于不需要进行删除操作,直接返回root就可以了;对于情况②来说,直接删除叶子节点就OK了;对于情况③,让右孩子补上原先的位置就行;对于情况④,让左孩子补上原先位置就可以了;情况⑤稍微复杂一些,我们可以考虑让右孩子来替代被删除的节点,同时再让左子树的部分成为右子树中最左侧的节点的左子树。这样就把所有可能出现的情况分析完了,然后再按照这种思路编写代码。代码如下:

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

        Day22打卡!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值