题目:
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),
使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。
节点的右子树仅包含键 大于 节点键的节点。
左右子树也必须是二叉搜索树。
注意:本题和 1038 相同
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/57887da8f199516c21a2ed980874c48b.png)
输入:[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]
示例 2:
输入:root = [0,null,1]
输出:[1,null,1]
示例 3:
输入:root = [1,0,2]
输出:[3,3,2]
示例 4:
输入:root = [3,2,4,1]
输出:[7,9,4,10]
-------------
思路:
一看到累加树,相信很多小伙伴都会疑惑:如何累加?遇到一个节点,然后在遍历其他节点累加?
怎么一想这么麻烦呢。
然后再发现这是一棵二叉搜索树,二叉搜索树啊,这是有序的啊。
那么有序的元素如果求累加呢?
其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],
求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。
为什么变成数组就是感觉简单了呢?
因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,
看起来就别扭了一些是不是。
那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺序是右中左,
所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了。
递归:
遍历顺序如图所示:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c5598736313d6860441cc3686ccf95ed.png)
迭代法:
迭代法其实就是中序模板题了,在二叉树:前中后序迭代法和二叉树:前中后序统一方式迭代法
可以选一种自己习惯的写法。
----------------
代码:反向中序遍历 + 全局sum 记录
class Solution{
int sum = 0;
public TreeNode convertBST(TreeNode root){
dfs(root);
return root;
}
public void dfs(TreeNode root){
if(root==null) return;
dfs(root.right);
sum += root.val;
root.val = sum;
dfs(root.left);
}
}
二叉树小总结:
涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定前序,都是先构造中节点。
求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。
注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序,
二叉树:找所有路径也用了前序,这是为了方便让父节点指向子节点。
力扣链接