Path Sum III

Path Sum III

update Jun 27, 2017

leetcodearrow-up-right

You are given a binary tree in which each node contains an integer value.

Find the number of paths that sum to a given value.

The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).

The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

Example:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

        10
       /  \
      5   -3
     / \    \
    3   2   11
   / \   \
  3  -2   1

Return 3. The paths that sum to 8 are:

  1. 5 -> 3

  2. 5 -> 2 -> 1

  3. -3 -> 11

解释下:这道题的意思就是说找任意path上相邻节点的和是 given sum value 的数量。 思路: 这道题目的难点是要考虑从上到下每一段path上nodes的和。我们可以写两个 recursive function, 外层的用来对每个node(做为root)考虑其子树中的所有path。而内层 function 则用来考虑包含该 node(做为root)的所有path。 细节: 对于内层function,每次调用下一层时候,传入下层的 sum 变为 sum - node.val,这样当下层 val == sum 的时候,就说明有了一条满足条件的path。

Python Code:

Java code:

update Jan 27,2018 19:58

Update PreSum 数组 解法

还是利用 dfs,逐层向下构建当前path,不同的是path中存储的是之前每个node.val组成的数组的preSum数组,如此一来每层我们都可以用 O(path.size) 的时间查看目前为止有多少以该节点为终点的路径其 sum 为给定值,优化了时间复杂度。

时间复杂度: 时间应该为 O(NlogN) 因为每次需要 O(当前depth) 的时间来遍历presum数组,而depth最高为 logN ,一共有 N 个节点,所以上界应该为 O(NlogN); 空间复杂度为 O(height);

  • Java Code:

  • C++ Code:

update 2018-06-29 20:31:55

Update: 使用 prefix sum + HashMap,最快解法

最初的解法是维持一个path,每到一个新的node,就向上遍历path,看有无 sum==target 的情况,这种做法的时间复杂度为 O(N*(logN^2))

进一步优化,把path改成 prefix sum array,这样时间复杂度就变为了 O(NlogN)

接下来,我们可以继续优化,使用 HashMap 来存储 prefix sums,即在 map 中存当前path中的 prefix sums 以及其个数,每次到了新node,向上query的时间变为 O(1),总时间复杂度降为 O(N);