代码随想录DAY23 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树

669. 修剪二叉搜索树

对于递归思想和二叉搜素树的理解

递归直接返回上一级

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
         if(root==nullptr){
            return root;
        }

        //剪枝过程,就是寻找[low,high]之间的节点
        //整个左部都不要了,要右部的符合条件的节点直接返回上一级
        if(root->valright,low,high);
            return right;
        }

        if(root->val>high){
            TreeNode*left=trimBST(root->left,low,high);
            return left;
        }

        //就是之前的right
        if(root->left) root->left=trimBST(root->left,low,high);
        if(root->right) root->right=trimBST(root->right,low,high);
        return root;
    }
};

非递归写法

找到合理的范围,root 的子树就存在不符合条件的,修剪root的子树

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
         if(root==nullptr) return root;

        //查找对应的节点范围(root 都是合乎条件的)
        while(root!=nullptr&&(root->valval>high)){
            if(root->val>low) root=root->left;
            else root=root->right;
        }

        //root 的孩子节点存在不符合条件的所以开始修剪
        TreeNode*cur=root;
        while(cur!=nullptr){
            while(cur->left!=nullptr&&cur->left->valleft=cur->left->right;
            }
            cur=cur->left;
        }
        cur=root;
        while(cur!=nullptr){
            while(cur->right!=nullptr&&cur->right->val>high){
                cur->right=cur->right->left;
            }
            cur=cur->right;
        }


        return root;
    }
};

108.将有序数组转换为二叉搜索树

递归类似于二分法,每次将数组分成两半去找根

class Solution {
public:
    TreeNode* transfer(vector& nums,int low,int high){
        if(nums.size()==0){
            return nullptr;
        }

        int mid=(low+high)/2;

        TreeNode*root=new TreeNode(nums[mid]);

        vector leftree(nums.begin(),nums.begin()+mid);
        vector rightree(nums.begin()+mid+1,nums.end());
        root->left=transfer(leftree,0,leftree.size());
        root->right=transfer(rightree,0,rightree.size()-1);
        return root;
    }

    TreeNode* sortedArrayToBST(vector& nums) {
        if(nums.size()==0){
            return nullptr;
        }

        return transfer(nums,0,nums.size()-1);
    }
};

非递归,类似于层序遍历

使用queue,因为queue能够保持输入输出顺序不变,更简单

第一个栈,模拟树的每一层

第二个栈,确定左子树的范围变化

第三个栈,确定右子树的范围变化

在循环中,首先需要确定树的范围,找到中间节点的值。接着分别对左右子树操作,不断将左右子树的范围放进后两个栈里。

这三个栈一定要同步。

第一个循环一定要考虑好。

先找到点,后赋值,接着将左右子树加入队列。

class Solution {
public:
    TreeNode* sortedArrayToBST(vector& nums) {
        if(nums.size()==0) return nullptr;

        queue mynode;
        queue leftque;
        queue rightque;

        TreeNode*root=new TreeNode(0);
        mynode.push(root);
        leftque.push(0);
        rightque.push(nums.size()-1);

        while(!mynode.empty()){
            //首先寻找中间节点并且赋值给根节点
            int left=leftque.front(); leftque.pop();
            int right=rightque.front(); rightque.pop();
            int mid=(left+right)/2;
            //重点在于把下一个加入到mynode里面
            TreeNode*cur=mynode.front(); mynode.pop();
            cur->val=(nums[mid]);

            //左子树确定范围
            if(leftleft=leftree;
                mynode.push(cur->left);
                leftque.push(left);
                rightque.push(mid-1);
            }

            //右子树确定范围
            if(right>mid){
                TreeNode*rightree=new TreeNode;
                cur->right=rightree;
                mynode.push(cur->right);
                leftque.push(mid+1);
                rightque.push(right);
            }

        }

        return root;
    }
};

538.把二叉搜索树转换为累加树 

遍历过程中改数

右中左

class Solution {
public:
    void transfer(TreeNode*root,int &addnum){
        if(root==nullptr) return;

        if(root->right) transfer(root->right,addnum);

        addnum+=root->val;
        root->val=addnum;

        if(root->left) transfer(root->left,addnum);
    }

    TreeNode* convertBST(TreeNode* root) {
        if(root==nullptr) return nullptr;
        int addnum=0;
        transfer(root,addnum);
        return root;
    }
};

对二叉树的统一遍历掌握还不是很熟

你可能感兴趣的:(算法,leetcode,数据结构,c++)