437. Path Sum III - JS

Description

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

Solution 1:

Time complexity: O(n^2) => for each node, traverse its subtree, and there are n nodes => n^2

For each node, we treat it as the starting node as the path, and count how many paths starting from it.

  • we need to call pathSum() for every node in the tree;
  • we also need to count how many satisfied paths starting from current node dfs()
1
2
3
4
5
6
7
8
9
10
11
12
13
let pathSum = function(root, sum) {
if( root === null ) return 0;
return dfs(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);;
};

// dfs() is just the count starting from the specified node,
// and need to add counts starting from it's children.
function dfs( node, sum ){
let res = 0;
if( node === null ) return 0;
if( node.val === sum ) res++;
return res + dfs(node.left, sum-node.val) + dfs(node.right, sum-node.val);
}

Solution 2:

Time complexity: O(n)

All the satisfied paths must be encountered when we traversal all the paths from root using dfs.

  • while doing DFS, we can make use of the current path, to check if there is a satisfied path on it.
  • The checking process is like “LC560. subarray sum equals k”,
    • we maintain a map of <prefixSum, freq>
    • for current node, we check if map has counterpart = curSum+node.val - sum
    • after finishing the visit of current node (i.e. done the visits of its children), we decrease its freq
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let pathSum = function(root, sum) {
let cnt = 0;
let map = new Map();
map.set(0, 1);
dfs(root, 0);
return cnt;


function dfs( node, curSum ){
if( node === null ) return;

let counterpart = curSum + node.val - sum;
if( map.has(counterpart) ) cnt += map.get(counterpart);

if( !map.has(curSum+node.val) ) map.set(curSum+node.val, 0);
map.set(curSum+node.val, map.get(curSum+node.val)+1);

dfs( node.left, curSum+node.val );
dfs( node.right, curSum+node.val );

map.set(curSum+node.val, map.get(curSum+node.val)-1);
}
};