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

669. 修剪二叉搜索树

迭代

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        while(root!=NULL&&(root->val<low||root->val>high)){
            if(root->val<low){
                root=root->right;
            }else if(root->val>high){
                root=root->left;
            }
        }
        if(root==NULL) return root;
        TreeNode* node=root;
        while(node->left!=NULL){
            if(node->left->val<low){
                node->left=node->left->right;
            }else{
                node=node->left;
            }
        }
        node=root;
        while(node->right!=NULL){
            if(node->right->val>high){
                node->right=node->right->left;
            }else{
                node=node->right;
            }
        }
        return root;
    }
};

这题要注意的就是树的根节点可能会变,并且由于搜索树的左节点小于节点,右节点大于节点,所以并不能在修建过程中,遇到左节点小于low或右节点大于high就直接将以左节点或右节点为根节点的子搜索树全部删除。左节点小于节点,右节点大于节点,意味着当节点小于low时,节点的左节点及以下节点都小于low,而又节点及以下则有可能大于low,大于high的节点同理。所以修剪的原理就是首先找到落在区间内的root,这一步没有坑。然后从root开始向左右修建,遇到小于low的左节点,就将左节点令为原左节点的右节点,遇到大于high的右节点,就将右节点令为原右节点的左节点。

递归

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(root==NULL) return root;
        if(root->val>high) return trimBST(root->left,low,high);
        if(root->val<low) return trimBST(root->right,low,high);
        root->left=trimBST(root->left,low,high);
        root->right=trimBST(root->right,low,high);
        return root;
    }
};

递归也是一样的原理,先找到落在区间内的root,再向左右节点开始修剪,修剪原理也相同。

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

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        queue<pair<int,int>>ranges;
        queue<TreeNode*>nodes;
        ranges.push({0,nums.size()-1});
        nodes.push(new TreeNode());
        TreeNode* root=nodes.front();
        while(!ranges.empty()){
            pair<int,int>rg=ranges.front();
            ranges.pop();
            TreeNode* node=nodes.front();
            nodes.pop();
            int tmp=(rg.second+rg.first)/2;
            node->val=nums[tmp];
            if(tmp!=rg.first){
                ranges.push({rg.first,tmp-1});
                node->left=new TreeNode();
                nodes.push(node->left);
            }
            if(tmp!=rg.second){
                ranges.push({tmp+1,rg.second});
                node->right=new TreeNode();
                nodes.push(node->right);
            }
        }
        return root;
    }
};

这题的关键在于要使搜索树为平衡二叉树,也就是要使树中所有节点的左侧与右侧的节点数量尽量相等。所以再构建树的过程中,不难简单的取数组的两端,而是取数组的中间元素,这就要求我们不断对数组进行分割,直到只剩一个元素。笔者采用两个队列,一个队列存放分割后的区间两端索引,一个存放节点地址。在取出一个区间与节点后,将区间的中间值赋给节点,以中间值的索引为分界,对数组进行分割,加入队列,循环往复。

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

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* convertBST(TreeNode* root) {
        if(root==NULL) return root;
        stack<TreeNode*>s;
        s.push(root);
        int sum=0;
        while(!s.empty()){
            TreeNode* node=s.top();
            s.pop();
            if(node!=NULL){
                if(node->left!=NULL) s.push(node->left);
                s.push(node);
                s.push(NULL);
                if(node->right!=NULL) s.push(node->right);
            }else{
                node=s.top();
                s.pop();
                sum+=node->val;
                node->val=sum;
            }
        }
        return root;
    }
};

这题比较简单,只要将普通的左中右中序遍历反过来变为右中左中序遍历,再加一个求和的功能即可,要实现右中左,只需调换压入左节点与右节点的顺序即可。

代码随想录 第六章 二叉树part08

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值