问题
给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node的新值等于原树中大于或等于node.val的值之和
提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键小于节点键的节点
- 节点的右子树仅包含键大于节点键的节点
- 左右子树也必须是二叉搜索树
示例 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]
解法一:递归
反中序遍历二叉搜索树,记录过程中的节点值之和,顺序累加,并不断更新当前遍历到的节点的节点值
class Solution {int sum = 0;public TreeNode convertBST(TreeNode root) {if(root != null){convertBST(root.right);sum += root.val;root.val = sum;convertBST(root.left);}return root;}}
- 时间复杂度:
,其中
n是二叉搜索树的节点数。每一个节点恰好被遍历一次 - 空间复杂度:
,为递归过程中栈的开销,平均情况下为
,最坏情况下树呈现链状,为
可以通过一个pre指针记录当前遍历节点cur的前一个结点
递归函数参数以及返回值
- 不需要返回值
- 定义一个全局变量
pre,用于保存cur节点的前一个节点的数值int pre;void traversal(TreeNode cur);
确定终止条件
if(cur == null) return null;
确定单层递归逻辑
右中左来遍历二叉树,中节点的处理逻辑就是让
cur加上前一个节点的数值traversal(cur.right);cur.val += pre;pre = cur.val;traversal(cur.left);
class Solution {int pre; // 记录前一个节点的数值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;}}
解法二:迭代
class Solution {int pre; // 记录前一个节点的数值public void traversal(TreeNode root) {Deque<TreeNode> st = new LinkedList<TreeNode>();TreeNode cur = root;while (cur != null || !st.isEmpty()) {if (cur != null) {st.push(cur);cur = cur.right; // 右} else {cur = st.pop(); // 中cur.val += pre;pre = cur.val;cur = cur.left; // 左}}}public TreeNode convertBST(TreeNode root) {pre = 0;traversal(root);return root;}}
