把二叉搜索树转换为累加树
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 31 ms, 内存: 18.2 MB
/*
* 思路:
* 1. 我们将树中的节点值存储到一个列表中。
* 2. 对列表进行降序排序。
* 3. 使用累加器计算节点值的前缀和。
* 4. 使用哈希映射存储节点值及其对应的前缀和。
* 5. 再次遍历树并更新节点值。
*/
import java.util.*;
import java.util.stream.Collectors;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
public TreeNode convertBST(TreeNode root) {
if (root == null) return null;
List<Integer> values = new ArrayList<>();
inOrder(root, values);
List<Integer> sortedValues = values.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
Map<Integer, Integer> prefixSumMap = new HashMap<>();
int sum = 0;
for (int value : sortedValues) {
sum += value;
prefixSumMap.put(value, sum);
}
updateValues(root, prefixSumMap);
return root;
}
private void inOrder(TreeNode node, List<Integer> values) {
if (node != null) {
inOrder(node.left, values);
values.add(node.val);
inOrder(node.right, values);
}
}
private void updateValues(TreeNode node, Map<Integer, Integer> prefixSumMap) {
if (node != null) {
updateValues(node.left, prefixSumMap);
node.val = prefixSumMap.get(node.val);
updateValues(node.right, prefixSumMap);
}
}
}
解释
方法:
这个题解采用了递归的方法来实现二叉搜索树到累加树的转换。首先,定义了一个辅助函数 dfs,它采用反向中序遍历(即先访问右子树,再访问根节点,最后访问左子树)。在访问每个节点时,维护一个累加变量 s,这个变量保存了当前已访问节点的值的总和。当访问到一个节点时,将它的节点值更新为 s 加上该节点原始的值。由于二叉搜索树的特性,这种遍历顺序保证了每个节点可以直接获取到所有大于等于它的节点值的总和。
时间复杂度:
O(n)
空间复杂度:
O(n) in the worst case, O(log n) in the average case
代码细节讲解
🦆
为什么选择反向中序遍历(先右后左)而不是正向中序遍历(先左后右)来实现这个算法?
▷🦆
递归实现中使用了nonlocal关键字修改s,如果不使用nonlocal,算法还能正确运行吗?有什么替代的实现方式?
▷🦆
在递归函数中,如果二叉搜索树为null,直接返回None有哪些潜在的问题或者考虑?
▷