Leetcode 538 把二叉搜索树转换为累加树
理解题意:
所谓累加树:对于每个节点,将所有比它大的点累加于这一点。
而二叉搜索树:任何一个中间节点,都大于左子树任何节点,小于右子树所有节点。
而二叉搜索树中序排列是严格单调递增的序列。
所以二叉搜索树累加树的话,则是将右子树的节点加到中间节点,再将中间节点加到左子树。
从中序序列来看,可以使用双指针节点,一个pre指针,一个cur指针。从后往前遍历,将pre指向比cur大的值,始终将pre加到cur。
从树的结构来看,pre之上前一位比cur值大的节点,cur指向当前最大的节点。
树的遍历顺序为:右中左。
解题方法:
递归 迭代
1.递归
节点处理顺序为右中左,pre总是指向比当前值大的值的累加和。
public TreeNode convertBST(TreeNode root) {
AddBST(root);
return root;
}
//指向比当前值大的值的累加
int pre=0;
public void AddBST(TreeNode cur) {
if(cur==null)return;
if(cur.right!=null){
AddBST(cur.right);
}
cur.val+=pre;
pre=cur.val;
if(cur.left!=null) AddBST(cur.left);
}
2.迭代
入栈顺序总是左中右,出栈顺序右中左,pre总是指向比当前值大的值的累加和。
public TreeNode convertBST(TreeNode root) {
if(root==null) return root;
int pre=0;
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur=stack.pop();
if(cur!=null){
if(cur.left!=null) stack.push(cur.left);
stack.push(cur);
stack.push(null);
if(cur.right!=null) stack.push(cur.right);
}else{
cur=stack.pop();
cur.val+=pre;
pre=cur.val;
}
}
return root;
}
3.分析
时间复杂度:
递归:O(n)
迭代:O(n)
空间复杂度:
递归:O(n)
迭代:O(2n)