路径总和 III 算法讲解
一、引言
在二叉树相关的算法问题中,“路径总和 III” 是一个经典且具有一定难度的题目。它要求我们在二叉树里找出节点值之和等于给定目标值的路径的数目,并且路径不需要从根节点开始,也不需要在叶子节点结束,但方向必须是向下的(从父节点到子节点)。这就需要我们巧妙地运用二叉树的遍历和一些数据结构的特性来解决。
二、问题分析
给定一个二叉树的根节点 root
和一个整数 targetSum
,我们的任务是统计满足节点值之和等于 targetSum
的路径数量。
例如,对于以下二叉树:
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
当 targetSum = 8
时,满足条件的路径有 3 条。
三、解题思路
暴力解法
最直接的想法是对二叉树进行深度优先搜索(DFS),对于每个节点,从它开始向下进行深度优先搜索,计算以该节点为起点的所有路径和,判断是否等于 targetSum
。这种方法时间复杂度较高,对于每个节点都要进行一次从该节点出发的完整路径搜索,时间复杂度为 O(n2)O(n^2)O(n2),其中 nnn 是二叉树的节点个数。
优化解法 - 前缀和 + 深度优先搜索
我们可以使用前缀和的思想结合深度优先搜索来优化算法。
- 前缀和数组:定义一个哈希表
prefixSumCount
来记录从根节点到当前节点的路径上的前缀和出现的次数。前缀和就是从根节点到当前节点的路径上所有节点值的累加和。 - 深度优先搜索:在进行深度优先搜索时,对于当前节点,计算从根节点到它的路径和
currentSum
。然后检查currentSum - targetSum
是否在哈希表中出现过,如果出现过,说明存在一条从之前某个节点到当前节点的路径,其节点值之和等于targetSum
,将对应的路径数量累加到结果中。 - 回溯:在递归返回之前,需要将当前节点的前缀和出现次数减 1,这是为了保证在回溯到父节点时,不影响父节点的路径计算,避免重复计算路径。
四、示例代码(Java)
class TreeNode {
int val;