题目
给定一个二叉搜索树,请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。
节点的右子树仅包含键 大于 节点键的节点。
左右子树也必须是二叉搜索树。
思路
一棵二叉搜索树,所以对其进行一次中序遍历后,得到的数组一定是有序的。而题目说,要将每个节点替换成大于或者等于该节点值的所有节点值之和!
因为列表是有序的,可以模拟一下后缀和数组的思路,将每个数字的后缀和(即大于或者等于该节点的值的所有节点值之和)存放到一个哈希表里,然后再进行一个层次遍历,将每个节点的值替换成它的哈希表里面的后缀和即可!
代码
class Solution {
public TreeNode convertBST(TreeNode root) {
if(root==null)
return null;
Stack<TreeNode> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
TreeNode copyRoot = root;
TreeNode copyRoot_1=root;
// 中序遍历,可以拿到整棵树的每个节点的值的升序数组
while(root!=null || !stack.isEmpty())
{
while(root!=null)
{
stack.push(root);
root=root.left;
}
root=stack.pop();
list.add(root.val);
root=root.right;
}
// 模拟后缀和数组,将每个节点的后缀和存储在哈希表里面
int size = list.size();
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
map.put(list.get(size-1),list.get(size-1));
for (int i=size-2;i>=0;--i)
{
map.put(list.get(i),list.get(i)+map.get(list.get(i+1)));
}
// 再进行一次层序遍历,将每个节点的值替换为其后缀和
Deque<TreeNode> deque = new LinkedList<>();
deque.add(copyRoot);
while(!deque.isEmpty())
{
TreeNode temp = deque.poll();
temp.val=map.get(temp.val);
if(temp.left!=null)
deque.add(temp.left);
if(temp.right!=null)
deque.add(temp.right);
}
return copyRoot_1;
}
}
结果
还可以,算是中等难度的题目,卡点在那个后缀和数组那里,刚刚拿到题目有点想不通!其他的,不算很难!