本文主要是介绍剑指Offer || 050.路径总和|||,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目
给定一个二叉树的根节点 root
,和一个整数 targetSum
,求该二叉树里节点值之和等于 targetSum
的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例 1:
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8 输出:3 解释:和等于 8 的路径有 3 条,如图所示。
示例 2:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:3
提示:
- 二叉树的节点个数的范围是
[0,1000]
-109 <= Node.val <= 109
-1000 <= targetSum <= 1000
注意:本题与主站 437 题相同:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
LCR 050. 路径总和 III - 力扣(LeetCode)
题解
思路一:暴力解法,枚举每个结点作为根,在对枚举的每颗子树进行dfs(即两次dfs),判断是否存在targetSum。 注意:过程sum可能会溢出,故设为long。
代码:
class Solution {long target;int ans = 0;public void dfs(TreeNode t, long sum) {if (t == null) return;if (sum + t.val == target)ans++;dfs(t.left, sum + t.val);dfs(t.right, sum + t.val);}public void dfs1(TreeNode t){if(t == null) return;dfs(t, 0);dfs1(t.left);dfs1(t.right);}public int pathSum(TreeNode root, int targetSum) {this.target = targetSum;dfs1(root);return ans;}
}
思路二:前缀和思想。每次到一个新的结点,总是会重复计算结点间的路径和,于是可以使用一个map<从根节点到当前结点的路径长度,有多少条该路径>,来记录路径sum,然后当前sum-之前的sum==target的,即是一条路径。
有两个点需要注意:1.根节点为空路径,map要添加<0,1>。
2.每个子树操作完之后,要消除该子树对其他子树的影响,即map的value值是会减少的。
代码:
class Solution {//map<从根节点到当前结点的路径长度,有多少条该路径>Map<Long, Integer> sumCountMap = new HashMap<Long, Integer>();public int pathSum(TreeNode root, int targetSum) {if (root == null) return 0;sumCountMap.put(0L, 1);//起点的空路径return getCounts(root, root.val, targetSum);}public int getCounts(TreeNode node, long sum, int targetSum) {//递归的每个子树里都有一个新的count加进来。int count = sumCountMap.getOrDefault(sum - targetSum, 0);sumCountMap.put(sum, sumCountMap.getOrDefault(sum, 0) + 1);if (node.left != null) count += getCounts(node.left, sum + node.left.val, targetSum);if (node.right != null) count += getCounts(node.right, sum + node.right.val, targetSum);//从子树里退出去的时候,消除当前的sum数量对其他子树的影响sumCountMap.put(sum, sumCountMap.get(sum) - 1);return count;}
}
这篇关于剑指Offer || 050.路径总和|||的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!