package wsy.letcode.bstToGst;
import java.util.Stack;
/**
* 给出二叉搜索树的根节点,该二叉树的节点值各不相同,修改二叉树,使每个节点 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 之间。
* 给定的树为二叉搜索树。
*
*
*
*/
public class BstToGst {
/**
* 思路:利用栈后进先出的特性,从根结点往右子树遍历,所经历结点全部进栈
* 直到结点没有右孩子
* 缓存一个存储和值的变量add,将栈顶元素出栈,即最右结点赋值给add,如果此结点存在左孩子,则左孩子及其左孩子的右子树继续入栈,循环往返。
*
* 总之,遵循先右后左的处理规则
*
*/
public TreeNode bstToGst(TreeNode root) {
if (root == null) {
return root;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
// 缓存求和值
int add = 0;
// 树的最右边结点依次入栈
addStack(stack, root);
while (!stack.isEmpty()) {
// 栈顶元素出栈
TreeNode pop = stack.pop();
// 将缓存的和值叠加到该结点上
pop.val += add;
// 然后将该结点的值赋值给add
add = pop.val;
// 如果出栈元素存在左孩子,则左孩子及左孩子组成的子树的最右结点依次入栈
if (pop.left != null) {
addStack(stack, pop.left);
}
}
return root;
}
private void addStack(Stack<TreeNode> stack, TreeNode node) {
TreeNode right = node;
while (right!= null) {
stack.push(right);
right = right.right;
}
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
本解法时间复杂度可能稍微高些,但空间效率非常高,可以继续优化,欢迎留言。