代码随想录算法训练营Day23| 669. 修剪二叉搜索树 , 108.将有序数组转换为二叉搜索树 , 538.把二叉搜索树转换为累加树

669. 修剪二叉搜索树代码随想录

今天这第一题我是真的有点醍醐灌顶了,在听到解析之后,我没有考虑到的情况是不能直接return他的left或者right,因为他的left或者right里还有不符合条件的,所以这里应该返回的是修剪过后的left或者right,这里真的很容易搞错,一开始就以为是一个简单的找到,然后再用之前的删除节点的操作就可以了,来看一下具体代码的实现

TreeNode* trimBST(TreeNode* root, int low, int high) {
        return CutNode(root,low,high);
    }
    TreeNode* CutNode(TreeNode* &root, int low,int high){
        if(root==NULL) return NULL;
        root->left = CutNode(root->left,low,high);
        if(root->val<low || root->val>high){
            if(root->left==NULL && root->right==NULL){
                return NULL;
            }
            else if(root->left==NULL && root->right!=NULL){
                return CutNode(root->right,low,high);
            }
            else if(root->left!=NULL && root->right==NULL){
                return CutNode(root->left,low,high);
            }
            else if(root->left!=NULL && root->right!=NULL){
                TreeNode* p=root->left;
                while(p->right!=NULL){
                    p=p->right;
                }
                if(p==root->left){
                    p->right=root->right;
                    return CutNode(root->left,low,high);
                }
                else{
                    p->right=root->right;
                    return CutNode(root->left,low,high);
                }
            }
        }
        root->right=CutNode(root->right,low,high);
        return root;
    }

这里其实不用额外定义一个函数,首先是递归的终止条件,当节点为NULL时,就直接返回NULL,然后就是中序遍历,用root的left来接收修建过后的左子树,后面的右子树也是一样的,然后就是单层递归的逻辑,只要这个结点的数值不满足题目的条件,那就先判断,如果是左右子树只存在一个的情况,那就分别返回他们左右子树修剪过后的值,如果是都存在的情况,那就是返回拼接好后的然后再修减过后的值,最后再返回根节点就可以了

108.将有序数组转换为二叉搜索树 :代码随想录

这道题目很简单,其实就是采用一个二分法的思想,不断地进行分割数组。然后递归的建立根结点,直到传入的数组为空时,代表此时应该建立的是空结点,来看具体代码的实现

TreeNode* sortedArrayToBST(vector<int>& nums) {
        if(nums.size()==0) return NULL;
        int mid=nums.size()/2;
        TreeNode* root=new TreeNode(nums[mid]);
        vector<int> leftnums;vector<int> rightnums;
        for(int i=0;i<mid;i++) leftnums.push_back(nums[i]);
        for(int i=mid+1;i<nums.size();i++) rightnums.push_back(nums[i]);
        root->left=sortedArrayToBST(leftnums);
        root->right=sortedArrayToBST(rightnums);
        return root;
    }

首先当数组的大小为零时,返回空,然后就是取中间值,然后建立lefttree和righttree然后递归建立即可

538.把二叉搜索树转换为累加树:代码随想录

这道题也非常的简单,我是先将所有节点的总和计算出来,然后再定义一个sum一直加结点的数值,然后再将总和减去sum即是所要变的累加值,当然浙题还有一个更巧妙的方法。那就是用右中左的顺序遍历,然后用双指针的思想,一开始pre为零,然后就一直让当前结点加上pre结点的数值,然后再让pre的值等于当前结点,这样就是让pre一直为前面结点数值的总和,然后又是从右边开始遍历,所以总和刚好就是数值比自己大的,最hi再加上自己本身,就转化为一个累加树了,所以我觉得这个方法还是非常的巧妙的。来看具体代码的实现

class Solution {
public:
        TreeNode* convertBST(TreeNode* root) {
        int sum=count(root);
        int c=0;
        ordered(root,sum,c);
        return root;
    }
    void ordered(TreeNode* &root,int sum,int &c){
        if(root==NULL) return ;
        ordered(root->left,sum,c);
        c+=root->val;
        root->val=sum-c+root->val;
        ordered(root->right,sum,c);
    }
    int count(TreeNode* root){
        if(root==NULL) return 0;
        int sum=root->val;
        int sumleft=count(root->left);
        int sumright=count(root->right);
        return sum+sumleft+sumright;
    }
};

这就是今天的总结,继续加油吧!明天下午考英语六级。明天还要开启新的章节——回溯,加油,天行健,君子以自强不息!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值