「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战」
把二叉搜索树转换为累加树
题目
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(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] 示例 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]
解法
首先,我们都知道二叉搜索树有个十分重要的特征就是有序,对二叉搜索树进行中序遍历得到的是一段从小到大的序列。而这道题目中累加树是按照右中左的顺序累加,这个顺序刚好和树的中序遍历相反,所以我们可以考虑对二叉搜索树做一个反中序遍历,然后做val值累加操作,这样就可以得到一颗累加树了
递归三要素
- 递归的终止条件:遍历的节点为空,此层递归终止
- 递归的参数及返回值:遍历的树的根节点,无需返回值
- 递归的单层逻辑:如果右子树不为空遍历右子树,然后更新val值,并设置preval为自身val,供下一个遍历节点使用,如果左子树不为空遍历右子树
var convertBST = function(root) {
// 保存上一个节点的值,初始值为0
let preVal = 0
// 这里是反中序遍历,右中左
const travelNode = function(node){
// 递归终止条件,节点不存在则返回
if(!node) return;
// 存在右子树则遍历右子树
node.right && travelNode(node.right);
// 更新节点值
node.val += preVal;
// 更新pre
preVal = node.val;
// 存在左子树则遍历左子树
node.left && travelNode(node.left);
}
// 从根节点开始遍历树
travelNode(root);
return root;
};