25-03-27
25-03-27 今日讨论
1)hot100-旋转图像
和螺旋矩阵比较像,记录 L|R|T|D
2) 路径总和|||
看了一会。
1、DFS
public class temp {
// 以root为根的这棵树中,满足条件的路径数
public static int pathSum(TreeNode root, long targetSum) {
if (root == null) return 0;
int count = rootSum(root, targetSum);
count += pathSum(root.left, targetSum);
count += pathSum(root.right, targetSum);
return count;
}
// 表示以 root 为根的满足条件的路径数,root节点必须包含在内
public static int rootSum(TreeNode root, long targetSum) {
int count = 0;
if (root == null) return 0;
int val = root.val;
if (val == targetSum) count++;
count += rootSum(root.left, targetSum-val);
count += rootSum(root.right, targetSum-val);
return count;
}
}
2、前缀和+Map
import java.util.*;
public class temp {
// DFS
public static int pathSum(TreeNode root, int targetSum) {
Map<Long, Integer> map = new HashMap<>();
map.put(0L,1);
int count = comp(root, targetSum, map, 0L);
return count;
}
public static int comp(TreeNode root, int targetSum, Map<Long, Integer> map, Long preSum) {
if (root == null) return 0;
int count = 0;
preSum += root.val;
count += map.getOrDefault(preSum - targetSum, 0);
map.put(preSum, map.getOrDefault(preSum, 0) + 1);
count += comp(root.left, targetSum, map, preSum);
count += comp(root.right, targetSum, map, preSum);
map.put(preSum, map.getOrDefault(preSum, 0) - 1);
preSum -= root.val;
return count;
}
}
1. 为什么 preSum -= root.val; 不影响结果?
preSum是Long类型,按值传递(Java 中基本类型和Long是按值传递的)。- 在递归调用
comp(root.left, ...)和comp(root.right, ...)时,preSum的值会被复制一份传递进去,递归调用的修改不会影响当前层的preSum。 - 因此,即使去掉
preSum -= root.val;,递归返回后,当前层的preSum仍然是原来的值(没有变化),不影响后续逻辑。
2. 为什么 map.put(preSum, ... - 1) 是必要的?
map是HashMap<Long, Integer>,它是引用传递(Java 中对象是按引用传递的)。- 在递归过程中,
map会被共享,所以必须回溯恢复状态,否则会影响其他递归分支的计算:- 进入递归前:
map.put(preSum, ... + 1)(记录当前路径和) - 递归结束后:
map.put(preSum, ... - 1)(撤销当前路径和的影响)
- 进入递归前:
- 如果不恢复
map,会导致其他路径的错误统计。
3. 为什么 preSum -= root.val; 可以去掉?
- 因为
preSum是按值传递的,递归调用不会改变当前层的值。 - 即使去掉
preSum -= root.val;,当前层的preSum仍然保持原值(递归返回后不受影响)。 - 但保留这一行可以让代码逻辑更清晰(显式地“回溯”
preSum,与map的回溯保持一致)。

浙公网安备 33010602011771号