一つ、タイトル説明
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
第二に、問題解決
方法の一つ:再帰
*私はほとんどが困惑しています。このタイトルは初めてです。
- Q1:なぜ多層再帰を使用しています。
A1は:後でパスの最初に発見されたルート・ノードではないかもしれない、リーフノードの終わりではないかもしれません。私たちが望むように、初めとして、各ノードは、列挙各ノードに行きます。
他とI、IIまたは変わりません。
int cnt;
public int pathSum(TreeNode root, int sum) {
if (root == null)
return 0;
dfs(root, sum);
pathSum(root.left, sum);
pathSum(root.right, sum);
return cnt;
}
void dfs(TreeNode root, int re) {
if (root == null) {
return;
}
if (re == root.val) {
cnt++;
}
dfs(root.left, re-root.val);
dfs(root.right, re-root.val);
}
複雑性分析
- 時間計算: 、
- 宇宙の複雑さ: 、
方法2:蓄積部
パス内の各ノードのために、私たちは、パスの一致があるかどうかを確認するために戻っノード列挙からです。
- Q1:私はパス、直接終端サイクルを見つけることができた後?
A1:反例ルート= [0,1,1]、和=であり 1、 答えは4です。 - Q2:なぜ反復が前方リストから?
A2:この組み合わせは、前のノードとの接合部の終わりを保証することができますので。- たとえば、次の背面に少なくとも一つの前部が横断する場合はA1の反例は、1考え、[1,0]は、検討しました。
int cnt = 0;
int sum = 0;
List<Integer> path = null;
public int pathSum(TreeNode root, int target) {
sum = target;
path = new ArrayList<>();
dfs(root);
return cnt;
}
private void dfs(TreeNode root) {
if (root == null) {
return;
}
path.add(root.val);
int t = 0;
for (int i = path.size()-1; i >= 0; i++) {
t += path.get(i);
if (t == sum) {
cnt++;
//break; 不能提前break [1],[1,0]
}
}
dfs(root.left);
dfs(root.right);
path.remove(path.size()-1);
}
複雑性分析
- 時間計算: 、
- 宇宙の複雑さ: 、
方法2:接頭辞と
マップはCUR和があれば、我々はノードCUR和現在のノード・パスから来るようになったことを証明することは正当なパスです。例えば:私たちは、その合計=パス11を知っています。我々はリーフノード3を行って、経路21、21 --11 = 10の合計は、プレフィクス10及び地図があってもよいです。
ボトムライン:あなたは接頭辞を持っているとし、CUR場合 - (CUR - - 合計)パスの合計が、また、現在およびCURのために、差CURがなければなりません。
10
/
5
/
3
/
3
int cnt = 0;
int sum = 0;
int cur = 0;
Map<Integer, Integer> map = null;
public int pathSum(TreeNode root, int target) {
map = new HashMap<>();
map.put(0, 1);
sum = target;
dfs(root);
return cnt;
}
private void dfs(TreeNode root) {
if (root == null) {
return;
}
cur += root.val;
cnt += map.getOrDefault(cur - sum, 0);
map.put(cur, map.getOrDefault(cur, 0) + 1);
dfs(root.left);
dfs(root.right);
// 回溯
cur -= root.val;
map.put(cur, map.get(cur) - 1);
}
複雑性分析
- 時間計算: 、
- 宇宙の複雑さ: 、