题目
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。
节点的右子树仅包含键 大于 节点键的节点。
左右子树也必须是二叉搜索树。
感想
第一次做二叉搜索树的题目??第一次读题的时候没有get到题目的要求,以及隐含的条件!我觉得可能是没有理解的那么透彻吧。
二叉搜索树:左的值<根的值<右的值
我能够分析到:
- 从根的右节点着手,最右边的节点不需要累加,也就是说遍历到叶子节点,就返回,然后不断累加值。
- 然后返回给root,root的值为root本身的值+右子树的所有结点的值;
- root再向左dfs,又是先遍历右子树,再是根,最后左子树。
但是写出来的代码,很长,而且也报错了,确实是自己的水平没有到,不能写出来
然后没有办法,只能去看看大佬写的代码:
写法一:递归
class Solution {
int preNum=0;
public TreeNode bstToGst(TreeNode root) {
dfs(root);
return root;
}
public void dfs(TreeNode root){
if(root==null){
return;
}
dfs(root.right);
root.val+=preNum;
preNum=root.val;
dfs(root.left);
}
}
写法二:非递归
借用栈来存储结点
public TreeNode bstToGst(TreeNode root) {
if (root == null)
return root;
TreeNode returnNode = root;
Stack<TreeNode> stack = new Stack<>();
int preNum = 0;
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.add(root);
root = root.right;
}
root = stack.pop();
root.val += preNum;
preNum = root.val;
root = root.left;
}
return returnNode;
}
反思
其实这道题本身是不难的,难的是我们对树的三种遍历方式的熟悉程度或理解程度,我之前做过树的三种遍历方式的题,只是现在都已经忘了,还是要多刷题来巩固自己的基础呀。