1题目
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node
的新值等于原树中大于或等于 node.val
的值之和。
提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键 小于 节点键的节点。
- 节点的右子树仅包含键 大于 节点键的节点。
- 左右子树也必须是二叉搜索树。
注意:本题和 1038: 力扣 相同
示例 1:
输入:[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链接
题目链接:538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)
视频链接:普大喜奔!二叉树章节已全部更完啦!| LeetCode:538.把二叉搜索树转换为累加树_哔哩哔哩_bilibili
3解题思路
二叉搜索树是可以看成有序数组的,有序数组的累加很简单的就能想到用双指针,那么二叉树同样适用。
使用一个指针pre和另一个指针cur递归遍历,右中左的顺序
1.递归参数及返回值
这里把pre定义成了一个整数,而不是指针。是因为考虑到对空指针操作可能会发生异常,反而代码更加复杂,用int类型的一样可以完成遍历。
int pre = 0; // 记录前一个节点的数值
void traversal(TreeNode* cur)
2.确定终止条件
思考一下,一直向右遍历直到cur==nullptr,这个时候停止并返回空(因为函数定义的返回值类型就是void)。返回为空后,自动跳出此轮递归,进入上一层递归,也就是cur指向的是最右下角的叶子结点。这时候pre表示0,开始累加。
if (cur == NULL) return;
3.确定单层递归逻辑
这一块还是比较好想的,就让cur->val一直加pre的值,然后再把这个值赋给pre。这就实现了利用递归移动类似双指针的操作,不过pre不是指针罢了。
traversal(cur->right); // 右
cur->val += pre; // 中
pre = cur->val;
traversal(cur->left); // 左
4代码
class Solution {
private:
int pre = 0; // 记录前一个节点的数值
void traversal(TreeNode* cur) { // 右中左遍历
if (cur == NULL) return;
traversal(cur->right);
cur->val += pre;
pre = cur->val;
traversal(cur->left);
}
public:
TreeNode* convertBST(TreeNode* root) {
pre = 0;
traversal(root);
return root;
}
};