LeetCode 21. 合并两个有序链表 | C++语言版
- LeetCode 36: 两个链表的第一个公共结点
- 题目描述
- 解题思路
- 思路一:使用前缀和
- 代码实现
- 运行结果
- 参考文章:
- 思路二:减少遍历节点数
- 代码实现
- 运行结果
- 参考文章:
LeetCode 36: 两个链表的第一个公共结点
题目描述
题目地址:437. 路径总和 III
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
解题思路
思路一:使用前缀和
代码实现
C++
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//HashMap的key是前缀和,value是前缀和为这个值的路径数量
Map<Long,Integer> prefixMap;
int target;
//遍历二叉树,对每个节点,记录前缀和的同时,返回当前找到和为target的路径数量。参数curSum表示node节点之前的前缀和。
private int recur(TreeNode node,Long curSum){
if(node==null) return 0;
//res记录路径数量
int res=0;
//curSum记录前缀和,遍历到当前节点的时候就加上这个节点的值。
curSum+=node.val;
//getOrDefault() 获取指定key对应的value,如果找不到key,则返回指定的默认值
//res就是路径数量。curSum是根节点到当前节点的前缀和(两节点间的路径和 = 两节点的前缀和之差),如果哈希表中能找到之前存在过路径的前缀和为curSum - target,说明可以找到value条路径使其路径和为target
res+=prefixMap.getOrDefault(curSum-target,0);
//把当前节点的前缀和也加入到哈希表中,如果已经存在了就给value + 1
prefixMap.put(curSum,prefixMap.getOrDefault(curSum,0)+1);
//再去遍历其左右子树继续记录前缀和并找可行路径
int left=recur(node.left,curSum);
int right=recur(node.right,curSum);
//全都遍历完了在把所有找到的路径加起来就是总的路径数量
res = res + left + right;
//最后记得在哈希表中把已经找过的路径都去掉,即恢复状态
prefixMap.put(curSum,prefixMap.get(curSum)-1);
return res;
}
//使用前缀和
public int pathSum(TreeNode root, int targetSum) {
prefixMap=new HashMap<>();
target=targetSum;
//key是前缀和,value是前缀和为这个值的路径数量。(因为可能好几条路径前缀和是同一个值。)。这里表示前缀和为0的路径有一条。(不这样做若某个节点的前缀和直接已经等于targetSum,此时反而会错过此路径)
prefixMap.put(0L,1);
//传入参数是根节点root,和root之前的前缀和0
return recur(root,0L);
}
}
运行结果
参考文章:
https://leetcode.cn/problems/path-sum-iii/solutions/596361/dui-qian-zhui-he-jie-fa-de-yi-dian-jie-s-dey6/
思路二:减少遍历节点数
代码实现
C++
在这里插入代码片