1.题目
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.
Example:
Input: The root of a Binary Search Tree like this: 5 / \ 2 13 Output: The root of a Greater Tree like this: 18 / \ 20 13
2.思路
关于树的题大部分都是用递归算法来做最容易。根据题意,则我们应该先修改关键值最大的结点,再依次修改它前面的结点。使用中序遍历的思想,画了一个草图,一种简单的中序遍历方法,从根结点的右侧开始,沿着树的的轮廓画一条线,经过所有的结点后回到根结点的左侧,先经过哪个结点的下面,哪个结点就记录在前面。如下图,则遍历结果是13,11,10,8,6,5,3.我们进行转换的顺序也是这个。
用sum值记录当前已遍历过结点总和,初始值为0. 本题中序遍历顺序,先右孩子,然后是父亲,最后处理左孩子,递归进行。由于遍历结果是由大到小,因此每个结点更新为 原值+sum 即可,(sum即为所有大于正在处理的结点的值和)再将sum值更新为当前结点的值。
3.算法
public TreeNode convertBST(TreeNode root) {
if(root==null)return null;
convert(root);
return root;
}
private int sum=0;
private void convert(TreeNode root){
if(root==null)return;
convert(root.right);
root.val=root.val+sum;
sum=root.val;
convert(root.left);
}
4.总结
现在有了一点小小的心得,就是关于树的就往递归方面想,因为二叉树结构的特殊性,还能拆分成更小的二叉树,因此适合递归的方法。
另外,关于sum值,也有要注意的地方,之前我是在convertBST方法里面,定义了sum值,传给convert(TreeNode,int),结果总是和预期有区别。思考之后,我明白了,我每次传入convert方法中的sum值,只是相当于传了一个sum的副本,不是传入了引用,因此并没有更新sum的值,在退出一层递归时,使用的sum值还是未更新的sum值,导致结果错误。