随想录训练营20/60 | LC 669. 修剪二叉搜索树;LC 108.将有序数组转换为二叉搜索树;LC 538.把二叉搜索树转换为累加树

文章介绍了三个关于二叉搜索树的问题:669题是修剪不在指定范围的节点,通过判断节点值与范围的关系,只保留符合条件的部分;108题将有序数组转换为平衡的二叉搜索树,采用中间元素作为根节点的方法;538题将二叉搜索树转换为累加树,通过反向中序遍历实现节点值的累加更新。
摘要由CSDN通过智能技术生成

LC 669. 修剪二叉搜索树

题目链接LC 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) {
        //终止条件
        if(root == nullptr)return nullptr;
        //递归规则
        //当不在规定区间时
        if(root->val<low){//比规定区间小,就去根节点的右子树(比根节点的值大)
            TreeNode* right = trimBST(root->right, low, high);
            return right;
        }
        else if(root->val>high){//比规定区间大,就去根节点的左子树(比根节点值小)
            TreeNode* left = trimBST(root->left, low, high);//看左子树是否符合
            return left;
        }
        //当在规定区间内时
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
        return root;
    }
};

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

题目链接LC 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) {
        //终止条件
        if(nums.size()==0)return nullptr;
        //递归逻辑
        //当只剩一个节点就构造一个节点直接返回
        TreeNode* cur = new TreeNode(0);
        int size = nums.size();
        if(size==1){
            cur->val = nums[0];
            return cur;
        }
        //当剩下多个,就寻找中心节点
        int midId = size/2;
        cur->val = nums[midId];
        vector<int> left(nums.begin(), nums.begin()+midId);
        vector<int> right(nums.begin()+midId+1, nums.end());
        cur->left = sortedArrayToBST(left);
        cur->right = sortedArrayToBST(right);
        return cur;
    }
};

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

题目链接LC 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:
    //遍历顺序为右中左,保存第一个值,之后每次用前面的值更新遍历的值,再保存
    int per = 0;//保存前面一个值,初始化为0是为了让第一个节点加0为本身,(不能设为-1,万一中间加的值等于-1就报错)
    void traversal(TreeNode* cur){
        //终止条件
        if(cur==nullptr)return;
        //否则进入递归逻辑
        //先进入右子树
        traversal(cur->right);
        //当到了最右叶子节点
        //若不是第一个节点
        cur->val = cur->val+per;
        per = cur->val;
        traversal(cur->left);
    }
    TreeNode* convertBST(TreeNode* root) {
        per = 0;
        traversal(root);
        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值