Leetcode-135周赛.5050. 从二叉搜索树到更大和树

5050. 从二叉搜索树到更大和树

题目难度 Medium

问题描述

给出二叉搜索树的根节点,该二叉树的节点值各不相同,修改二叉树,使每个节点 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]

提示:

树中的节点数介于 1 和 100 之间。
每个节点的值介于 0 和 100 之间。
给定的树为二叉搜索树。
解法

这道题想到了之前做过的类似的一个题目,也是修改树的内容。考虑到它修改的顺序是 后-中-先。直观上看没有一种遍历方式是这个顺序的,但是恰好与先序遍历的顺序相反,所以我们的做法是:

先进行先序遍历,用一个数组存储所有的结点。然后在数组中从后到前依次相加,直接改变数组中的节点的值,进行改变。注意数组中存储的是指针,所以改变数组就可以改变原来的树。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    
    void InOrderTraverse(TreeNode* T, vector<TreeNode*> &nums){
        if (T){
		InOrderTraverse(T->left,nums);
		nums.push_back(T);
		InOrderTraverse(T->right,nums);
	    }
    }
    
    TreeNode* bstToGst(TreeNode* root) {
        vector<TreeNode*> nums;
        InOrderTraverse(root,nums);
        int temp=0;
        for(int i=nums.size()-1;i>=0;i--){
            if(nums[i]==NULL)
                continue;
            nums[i]->val+=temp;
            temp=nums[i]->val;
        }
        return root;
    }
};

但实际上还是考虑复杂了,我们只需构建一种后-中-先遍历的方法,用一个整型的全局变量储存前面的和即可。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int cur;
    TreeNode* bstToGst(TreeNode* root) {
        cur = 0;
        dfs(root);
        return root;
    }
    
    void dfs(TreeNode* x) {
        if (x->right)	dfs(x->right);
        cur += x->val;
        x->val = cur;
        if (x->left)	dfs(x->left);
    }
    
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值