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 {// DFSpublic 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
的回溯保持一致)。