Skip to main content

113.路径总和 II

标签: tree, binary-search-tree, backtracking, depth-first-search

难度: Medium

通过率: 59.67%

原题链接: https://leetcode.com/problems/path-sum-ii/description/

题目描述

给定一个二叉树的根节点和一个整数目标和,返回所有从根节点到叶子节点路径的节点值之和等于目标和的路径。每条路径应该以节点值列表的形式返回,而不是节点引用。一个从根到叶子的路径是一个从根节点开始且以任何一个叶子节点结束的路径。一个叶子节点是没有子节点的节点。

解题思路

可以通过深度优先搜索 (DFS) 来解决这个问题。在遍历每个节点时,我们需要做以下几步:

  1. 将当前节点值加入到路径中。
  2. 判断当前节点是否是叶子节点,并且当前路径的和是否等于目标和,如果是,将此路径加入结果集中。
  3. 如果当前节点不是叶子节点,递归地去遍历它的左右子节点。
  4. 如果子树路径的递归返回后,移除当前节点值以回溯到父节点,尝试其他路径。

这种解决方案利用了回溯的思想,借助递归在二叉树中进行遍历,收集符合条件的路径。为了防止在遍历过程中路径污染,每次递归返回之后需要清理走过的路径(即从路径中移除最近加入的节点)。

代码实现

class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right

class Solution:
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
def dfs(node, current_path, current_sum):
if not node:
return

current_sum += node.val
current_path.append(node.val)

# 检查是否到达叶子节点并且路径和等于目标和
if not node.left and not node.right and current_sum == targetSum:
results.append(list(current_path))

# 递归遍历左子树和右子树
dfs(node.left, current_path, current_sum)
dfs(node.right, current_path, current_sum)

# 回溯,移除当前节点
current_path.pop()

results = []
dfs(root, [], 0)
return results

复杂度分析

时间复杂度: O(N2)O(N^2),其中 NN 是树中节点数目。在最坏情况下,我们可能需要从根节点遍历到所有叶子节点,而且需要复制每个路径的节点。对于每个叶子路径可能涉及 O(N)O(N) 的时间操作。 空间复杂度: O(N)O(N),主要是递归栈的空间和路径存储的空间。递归栈最多可能使用 O(N)O(N) 空间,而保存路径本身也需要 O(N)O(N) 的空间。