-
Notifications
You must be signed in to change notification settings - Fork 43
/
PathSum_ii.java
134 lines (103 loc) · 4.4 KB
/
PathSum_ii.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package LeetCodeJava.DFS;
// https://leetcode.com/problems/path-sum-ii/
import LeetCodeJava.DataStructure.TreeNode;
import java.util.ArrayList;
import java.util.List;
public class PathSum_ii {
// V0
// IDEA : DFS + backtracking
// NOTE !!! we have res attr, so can use this.res collect result
private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
if (root == null){
return this.res;
}
List<Integer> cur = new ArrayList<>();
getPath(root, cur, targetSum);
return this.res;
}
private void getPath(TreeNode root, List<Integer> cur, int targetSum){
// return directly if root is null (not possible to go further, so just quit directly)
if (root == null){
return;
}
// NOTE !!! we add val to cache here instead of while calling method recursively ( e.g. getPath(root.left, cur, targetSum - root.val))
// -> so we just need to backtrack (cancel last operation) once (e.g. cur.remove(cur.size() - 1);)
// -> please check V0' for example with backtrack in recursively step
cur.add(root.val);
if (root.left == null && root.right == null && targetSum == root.val){
this.res.add(new ArrayList<>(cur));
}else{
// NOTE !!! we update targetSum here (e.g. targetSum - root.val)
getPath(root.left, cur, targetSum - root.val);
getPath(root.right, cur, targetSum - root.val);
}
// NOTE !!! we do backtrack here (cancel previous adding to cur)
cur.remove(cur.size() - 1);
}
// V0'
// IDEA : DFS + backtracking V2
private List<List<Integer>> res2 = new ArrayList<>();
public List<List<Integer>> pathSum_2(TreeNode root, int targetSum) {
if (root == null){
return this.res2;
}
List<Integer> cur = new ArrayList<>();
getPath_2(root, cur, targetSum);
return this.res2;
}
private void getPath_2(TreeNode root, List<Integer> cur, int targetSum){
if (root == null){
return;
}
//cur.add(root.val);
if (root.left == null && root.right == null && targetSum == root.val){
// if condition meet, we add last val to cur
cur.add(root.val);
this.res2.add(new ArrayList<>(cur));
// and of course, we need to cancel previous adding
cur.remove(cur.size() - 1);
}else{
// NOTE !!! we add val to cur before recursive call, then we cancel it
cur.add(root.val);
getPath(root.left, cur, targetSum - root.val);
// cancel last adding
cur.remove(cur.size() - 1);
// NOTE !!! we add val to cur before recursive call, then we cancel it
cur.add(root.val);
getPath(root.right, cur, targetSum - root.val);
// cancel last adding
cur.remove(cur.size() - 1);
}
//cur.remove(cur.size() - 1);
}
// V1
// IDEA : DFS (RECURSION)
// https://leetcode.com/problems/path-sum-ii/editorial/
private void recurseTree(TreeNode node, int remainingSum, List<Integer> pathNodes, List<List<Integer>> pathsList) {
if (node == null) {
return;
}
// Add the current node to the path's list
pathNodes.add(node.val);
// Check if the current node is a leaf and also, if it
// equals our remaining sum. If it does, we add the path to
// our list of paths
if (remainingSum == node.val && node.left == null && node.right == null) {
pathsList.add(new ArrayList<>(pathNodes));
} else {
// Else, we will recurse on the left and the right children
this.recurseTree(node.left, remainingSum - node.val, pathNodes, pathsList);
this.recurseTree(node.right, remainingSum - node.val, pathNodes, pathsList);
}
// We need to pop the node once we are done processing ALL of it's
// subtrees.
pathNodes.remove(pathNodes.size() - 1);
}
public List<List<Integer>> pathSum_3(TreeNode root, int sum) {
List<List<Integer>> pathsList = new ArrayList<List<Integer>>();
List<Integer> pathNodes = new ArrayList<Integer>();
this.recurseTree(root, sum, pathNodes, pathsList);
return pathsList;
}
}