LeetCode热题(JS版) - 113. 路径总和 II

106 阅读2分钟

题目

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

给定如下二叉树,以及目标和 sum = 22,

markdownCopy code
          5
         / \
        4   8
       /   / \
      11  13  4
     /  \    / \
    7    2  5   1

返回:

csharpCopy code
[   [5,4,11,2],
   [5,8,4,5]
]

思路

实现该算法的关键是如何在二叉树中找到所有从根节点到叶子节点路径总和等于给定目标和的路径,并将其加入到结果集中。可以使用递归的方式遍历整棵二叉树,在每个节点处判断当前路径是否满足条件,并将满足条件的路径保存到结果集中。

下面是 Typescript 的代码实现:

function pathSum(root: TreeNode | null, sum: number): number[][] {
  const result: number[][] = []

  function dfs(node: TreeNode | null, targetSum: number, path: number[]) {
    if (!node) {
      return
    }
    if (!node.left && !node.right && node.val === targetSum) {
      result.push([...path, node.val])
      return
    }
    dfs(node.left, targetSum - node.val, [...path, node.val])
    dfs(node.right, targetSum - node.val, [...path, node.val])
  }

  dfs(root, sum, [])

  return result
}

首先,我们定义一个 result 数组用于保存所有满足条件的路径。然后,我们定义一个名为 dfs 的递归函数,该函数的参数包括以下内容:

  • node:当前遍历到的节点,初始值为根节点。
  • targetSum:从根节点到当前节点形成的路径应该满足的总和。
  • path:从根节点到当前节点形成的路径。

在 dfs 函数中,我们首先判断当前节点是否为空,如果是,则直接返回。然后,我们判断当前节点是否为叶子节点且路径的总和等于目标和,如果是,则将当前路径加入到结果集中。否则,我们继续递归地遍历当前节点的左右子树,并更新路径和。

最后,我们调用 dfs 函数,开始遍历整棵二叉树,并将得到的结果返回即可。

image.png

复杂度分析

  • 时间复杂度为 O(n)

对于每个节点而言,dfs 函数最多被调用一次,因此该算法的时间复杂度取决于遍历整棵二叉树所需的时间。由于每个节点最多只会被遍历一次,因此遍历整棵二叉树所需的时间是 O(n)。其中,n 是二叉树中节点的个数。

  • 空间复杂度为 O(n)

每次递归都会创建一个新的路径数组,因此该算法的空间复杂度取决于递归栈的深度和结果集的大小。在最坏情况下,二叉树的形态为一条链,递归栈的深度达到 n,结果集中保存了所有从根节点到叶子节点的路径,因此空间复杂度为 O(n)。