编程训练第一百一十七期——把二叉搜索树转换为累加树

这篇博客介绍了如何将二叉搜索树转换为累加树,使得每个节点的值等于原树中大于或等于其值的节点值之和。提供了两种解法:一是使用递归存储中序遍历结果,然后遍历更新节点值;二是直接反向中序遍历并更新节点值。两种方法的时间复杂度均为O(N),空间复杂度在最坏情况下为O(N)。
摘要由CSDN通过智能技术生成

编程问题:

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。


示例:

  • 输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
    输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
  • 输入:root = [0,null,1]
    输出:[1,null,1]
  • 输入:root = [1,0,2]
    输出:[3,3,2]
  • 输入:root = [3,2,4,1]
    输出:[7,9,4,10]

解法:

1.递归
由于此累加树实质上就是将每个结点的值更新为在中序遍历序列中排在自身后面结点值的累加,因此可以采用递归将中序遍历的结点存储在数组中,在通过一次遍历获得结点值总和,维护一个变量来记录排在前面结点的累加值,总和减去此累加值即为要更新的结果
时间复杂度O(N)
空间复杂度O(N)

/**
 * 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 {
private:
    void dfs(TreeNode* root)
    {
        if (root->left)
            dfs(root->left);
        tmp.push_back(root);
        if (root->right)
            dfs(root->right);
    }
public:
    vector<TreeNode*> tmp; 
    TreeNode* convertBST(TreeNode* root) {
        if (!root)
            return root;
        dfs(root);
        int sum = 0;
        int cur = 0;
        for (TreeNode* x : tmp)
            sum += x->val;
        for (TreeNode* x : tmp)
        {
            int val = x->val;
            x->val = sum - cur;
            cur += val; 
        }
        return root;
    }
};

或者直接反序中序遍历,维护一个变量来记录结点值的累加结果。
时间复杂度O(N)
空间复杂度O(N),为递归过程中栈的开销,平均情况下为 O(logN),最坏情况下树呈现链状,为 O(N)。

/**
 * 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 {
private:
    void dfs(TreeNode* root)
    {
        if (root->right)
            dfs(root->right);
        sum += root->val;
        root->val = sum;
        if (root->left)
            dfs(root->left);
    }
public:
    int sum = 0;
    TreeNode* convertBST(TreeNode* root) {
        if (!root)
            return root;
        dfs(root);
        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值