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

今天是二叉树学习的第八天。主要的学习内容有:修剪二叉搜索树,将有序数组转化为二叉搜索树,以及使用反中序遍历进行累加树的转换。

669. 修剪二叉搜索树

题目链接:669. 修剪二叉搜索树 - 力扣(LeetCode)

这个题目是给出一个范围,将二叉树中不在该范围的节点进行删除。我自己的做法是构造一个中序遍历和前序遍历数组,删除数组内不符合要求的数,然后根据调整过的中序数组和后序数组构建新的二叉搜索树。也通过了,但确实挺麻烦的。具体代码实现如下:
 

/**
 * 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:
vector<int> vec1;
vector<int> vec2;
    void inorder(TreeNode* root)
    {
        if(root==NULL) return;
        inorder(root->left);
        vec1.push_back(root->val);
        inorder(root->right);
    }
    void preorder(TreeNode* root)
    {
         if(root==NULL) return;
        preorder(root->left);
        preorder(root->right);
        vec2.push_back(root->val);
    }
    TreeNode* construct(vector<int> inorder,vector<int> behorder)
    {
        if(inorder.size()==0||behorder.size()==0) return NULL;
        int val=behorder[behorder.size()-1];
        TreeNode* root=new TreeNode(val);
        if(inorder.size()==1) return root;
        int i=0;
        for(i=0;i<inorder.size();i++)
        {
            if(inorder[i]==val) break;
        }
        vector<int> leftinorder(inorder.begin(),inorder.begin()+i);
        vector<int> rightinorder(inorder.begin()+i+1,inorder.end());
        behorder.resize(behorder.size()-1);
        vector<int> leftbehorder(behorder.begin(),behorder.begin()+leftinorder.size());
        vector<int> rightbehorder(behorder.begin()+leftinorder.size(),behorder.end());
        root->left=construct(leftinorder,leftbehorder);
        root->right=construct(rightinorder,rightbehorder);
        return root;
    }
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        inorder(root);
        preorder(root);
        vector<int> result1;
        vector<int> result2;
        for(int i=0;i<vec1.size();i++)
        {
            if(vec1[i]>=low&&vec1[i]<=high) result1.push_back(vec1[i]);
        }
        for(int i=0;i<vec2.size();i++)
        {
            if(vec2[i]>=low&&vec2[i]<=high) result2.push_back(vec2[i]);
        }
        TreeNode* node=construct(result1,result2);
        return node;
    }
};

后来学习了随想录的题解。首先递归函数的终止条件是遇到NULL就返回NULL值,处理的过程是如果该节点小于low,就递归处理该节点的右子树并返回处理后的右子树;如果该节点大于high,就递归处理该节点的左子树并返回处理后的左子树。使用root->left和root->right接住返回值。具体代码的实现过程如下:
 

/**
 * 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 NULL;
        if(root->val<low) 
        {
            TreeNode* node=trimBST(root->right,low,high);
            return node;
        }
        if(root->val>high) 
        {
            TreeNode* node=trimBST(root->left,low,high);
            return node;
        }
        root->left=trimBST(root->left,low,high);
        root->right=trimBST(root->right,low,high);
        return root;
    }
};

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

题目链接:108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)

这个题目和之前的前序中序构建二叉树思路是相似的。首先找出中间节点作为二叉搜索树的根节点,并以根节点为界划分左右子树,在递归处理左右子树即可。具体代码实现如下:
 

/**
 * 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* order(vector<int> nums,int left,int right)
    {
       if(left>right) return NULL;
        int mid=left+(right-left)/2;
        TreeNode* root=new TreeNode(nums[mid]);
        root->left=order(nums,left,mid-1);
        root->right=order(nums,mid+1,right);
        return root;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        TreeNode* result=order(nums,0,nums.size()-1);
        return result;
    }
};

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

题目链接:538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)

这个题目的要求是将二叉搜索树每个结点的值更新为一个逆向的累加和。如下图例子所示:

我自己的做法是中序遍历得到一个数组,然后翻转之后进行累加求和,再通过一个中序遍历进行每个节点值的更新。具体代码实现如下:

/**
 * 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:
vector<int> vec;
vector<int> result;
int i=0;
void order(TreeNode* root)
{
    if(root==NULL) return;
    order(root->left);
    vec.push_back(root->val);
    order(root->right);
}
void add(TreeNode* root)
{
    if(root==NULL) return;
    add(root->left);
    root->val=result[i++];
    add(root->right);
}
    TreeNode* convertBST(TreeNode* root) {
        if(root==NULL) return NULL;
        order(root);
        reverse(vec.begin(),vec.end());
        result.push_back(vec[0]);
        for(int i=1;i<vec.size();i++)
        {
            result.push_back(result[i-1]+vec[i]);
        }
        reverse(result.begin(),result.end());
        add(root);
        return root;

    }
};

后来看了代码随想录的题解。直接使用逆中序遍历,即右中左的遍历方法,通过双指针进行节点的值的更新。这样实现的效率更高,代码也更加简洁。具体代码实现如下:

/**
 * 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* pre=NULL;
    void order(TreeNode* root)
    {
        if(root==NULL) return;
        order(root->right);
        if(pre!=NULL) root->val=pre->val+root->val;
        pre=root;
        order(root->left);
    }
    TreeNode* convertBST(TreeNode* root) {
        order(root);
        return root;
    }
};

 

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值