Skip to content

Commit 63d1df4

Browse files
committed
leetcode
1 parent 323c919 commit 63d1df4

File tree

4 files changed

+472
-0
lines changed

4 files changed

+472
-0
lines changed

PathSumII/path_sum_II.dart

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/*
2+
3+
-* Path Sum II *-
4+
5+
6+
Given the root of a binary tree and an integer targetSum, return all root-to-leaf paths where the sum of
7+
the node values in the path equals targetSum. Each path should be returned as a list of
8+
the node values, not node references.
9+
10+
A root-to-leaf path is a path starting from the root and ending at any leaf node.
11+
A leaf is a node with no children.
12+
13+
14+
15+
Example 1:
16+
17+
18+
Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
19+
Output: [[5,4,11,2],[5,8,4,5]]
20+
Explanation: There are two paths whose sum equals targetSum:
21+
5 + 4 + 11 + 2 = 22
22+
5 + 8 + 4 + 5 = 22
23+
Example 2:
24+
25+
26+
Input: root = [1,2,3], targetSum = 5
27+
Output: []
28+
Example 3:
29+
30+
Input: root = [1,2], targetSum = 0
31+
Output: []
32+
33+
34+
Constraints:
35+
36+
The number of nodes in the tree is in the range [0, 5000].
37+
-1000 <= Node.val <= 1000
38+
-1000 <= targetSum <= 1000
39+
40+
41+
42+
43+
*/
44+
45+
// Definition for a binary tree node.
46+
import 'dart:collection';
47+
48+
class TreeNode {
49+
int val;
50+
TreeNode? left;
51+
TreeNode? right;
52+
TreeNode([this.val = 0, this.left, this.right]);
53+
}
54+
55+
class A {
56+
// global empty list - if i just use [] than it will end up with range error
57+
// so this is mos efficient way to create growable empty list
58+
List<List<int>> result = List.empty(growable: true)
59+
.map((e) => List<int>.empty(growable: true))
60+
.toList();
61+
List<List<int>> pathSum(TreeNode? root, int targetSum) {
62+
List<int> path = [];
63+
dfs(root, path, targetSum);
64+
return result;
65+
}
66+
67+
void dfs(TreeNode? node, List<int> path, int remainingSum) {
68+
// if it is null, then return
69+
if (node == null) return;
70+
// add the current node val to path
71+
path.add(node.val);
72+
// !node.left && !node.right : check if it is a leaf node
73+
// remainingSum == node.val: check if the remaining sum - node.val == 0
74+
// if both condition is true, then we find one of the paths
75+
if (node.left == null && node.right == null && remainingSum == node.val) {
76+
result.add(List.of(path, growable: true));
77+
}
78+
// traverse left sub tree with updated remaining sum
79+
// we don't need to check if left sub tree is null or not
80+
// as we handle it in the first line of this function
81+
this.dfs(node.left, path, remainingSum - node.val);
82+
// traverse right sub tree with updated remaining sum
83+
// we don't need to check if right sub tree is null or not
84+
// as we handle it in the first line of this function
85+
this.dfs(node.right, path, remainingSum - node.val);
86+
// backtrack
87+
path.remove(path.length - 1);
88+
}
89+
}
90+
91+
class B {
92+
// PreOrder DFS - dfs pre-order traversal
93+
// Runtime: 508 ms, faster than 100.00% of Dart online submissions for Path Sum II.
94+
// Memory Usage: 143.6 MB, less than 83.33% of Dart online submissions for Path Sum II.
95+
List<List<int>> pathSum(TreeNode? root, int targetSum) {
96+
// edge case
97+
if (root == null) return [];
98+
// empty growable list
99+
List<List<int>> result = List.empty(growable: true)
100+
.map((e) => List<int>.empty(growable: true))
101+
.toList();
102+
// list that will hold the node value
103+
List<int> visited = [];
104+
void traverse(TreeNode? node) {
105+
visited.add(node!.val);
106+
// life the both side of the node tree is null
107+
if (node.left == null && node.right == null) {
108+
// than our leaf value will be node value an reduce operator to do the sum of all values
109+
int leafSum = [...visited].reduce((a, b) => a + b);
110+
// if the sum same as our targetSum than we will ad the value in to visited list
111+
if (leafSum == targetSum) result.add([...visited]);
112+
}
113+
// if the left side of node have value we will retrieve the left value from root tree
114+
if (node.left != null) traverse(node.left);
115+
// if the right side of node have value we will retrieve the right value from root tree
116+
if (node.right != null) traverse(node.right);
117+
118+
visited.removeLast();
119+
}
120+
121+
// than we wil get the whole root
122+
traverse(root);
123+
124+
return result;
125+
}
126+
}
127+
128+
class C {
129+
// Recursive
130+
// Runtime: 506 ms, faster than 100.00% of Dart online submissions for Path Sum II.
131+
// Memory Usage: 154.4 MB, less than 50.00% of Dart online submissions for Path Sum II.
132+
List<List<int>> pathSum(TreeNode? root, int targetSum) {
133+
List<List<int>> paths = List.empty(growable: true)
134+
.map((e) => List<int>.empty(growable: true))
135+
.toList();
136+
137+
void dfs(root, sum, [List<int> current = const []]) {
138+
if (root == null) return;
139+
140+
List<int> newCurrent = [...current, root.val];
141+
if (root.left == null && root.right == null && sum == root.val)
142+
return paths.add(newCurrent);
143+
144+
dfs(root.left, sum - root.val, newCurrent);
145+
dfs(root.right, sum - root.val, newCurrent);
146+
}
147+
148+
dfs(root, targetSum);
149+
return paths;
150+
}
151+
}
152+
153+
class D {
154+
// Runtime: 557 ms, faster than 33.33% of Dart online submissions for Path Sum II.
155+
// Memory Usage: 149.7 MB, less than 50.00% of Dart online submissions for Path Sum II.
156+
List<List<int>> pathSum(TreeNode? root, int targetSum) {
157+
List<List<int>> res = List.empty(growable: true)
158+
.map((e) => List<int>.empty(growable: true))
159+
.toList();
160+
if (root == null) return res;
161+
162+
Queue<TreeNode?> nodeStack = Queue();
163+
Queue<int> sumStack = Queue();
164+
Queue<List<int>> pathStack = Queue();
165+
List<int> path = [];
166+
nodeStack.add(root);
167+
sumStack.add(root.val);
168+
path.add(root.val);
169+
pathStack.add(path);
170+
while (nodeStack.isNotEmpty) {
171+
TreeNode? node = nodeStack.removeLast();
172+
int tmp = sumStack.removeLast();
173+
path = pathStack.removeLast();
174+
if (node!.left == null && node.right == null) {
175+
if (tmp == targetSum) {
176+
res.add(path);
177+
}
178+
}
179+
180+
if (node.right != null) {
181+
nodeStack.add(node.right);
182+
sumStack.add(tmp + node.right!.val);
183+
}
184+
// avoid interfere left side which also uses the popped path
185+
List<int> pathCopy = [...path];
186+
pathCopy.add(node.right!.val);
187+
pathStack.add(pathCopy);
188+
189+
if (node.left != null) {
190+
nodeStack.add(node.left);
191+
sumStack.add(tmp + node.left!.val);
192+
path.add(node.left!.val);
193+
pathStack.add(path);
194+
}
195+
}
196+
return res;
197+
}
198+
}

PathSumII/path_sum_II.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package main
2+
3+
// Definition for a binary tree node.
4+
type TreeNode struct {
5+
Val int
6+
Left *TreeNode
7+
Right *TreeNode
8+
}
9+
10+
func pathSum(root *TreeNode, targetSum int) [][]int {
11+
var allPaths [][]int
12+
var currentPath []int
13+
14+
helper(root, currentPath, &allPaths, targetSum)
15+
16+
return allPaths
17+
}
18+
19+
func helper(root *TreeNode, currentPath []int, allPaths *[][]int, targetSum int) {
20+
if root == nil {
21+
return
22+
}
23+
24+
newCurrentPath := make([]int, len(currentPath))
25+
copy(newCurrentPath, currentPath)
26+
newCurrentPath = append(newCurrentPath, root.Val)
27+
28+
if root.Val == targetSum && root.Left == nil && root.Right == nil {
29+
*allPaths = append(*allPaths, newCurrentPath)
30+
} else {
31+
helper(root.Left, newCurrentPath, allPaths, targetSum-root.Val)
32+
helper(root.Right, newCurrentPath, allPaths, targetSum-root.Val)
33+
}
34+
}
35+
36+
// func pathSum(root *TreeNode, targetSum int) [][]int {
37+
// solution := make([][]int, 0)
38+
// if root == nil {
39+
// return solution
40+
// }
41+
42+
// return pathSumWith(root, targetSum, []int{}, solution)
43+
// }
44+
45+
// func pathSumWith(node *TreeNode, targetSum int, path []int, solution [][]int) [][]int {
46+
// if node == nil {
47+
// return solution
48+
// }
49+
50+
// targetSum -= node.Val
51+
52+
// newPath := make([]int, len(path))
53+
// copy(newPath, path)
54+
// newPath = append(newPath, node.Val)
55+
56+
// if node.Left == nil && node.Right == nil {
57+
// if targetSum == 0 {
58+
// solution = append(solution, newPath)
59+
// }
60+
// return solution
61+
// }
62+
63+
// return append(
64+
// pathSumWith(node.Left, targetSum, newPath, solution),
65+
// pathSumWith(node.Right, targetSum, newPath, solution)...,
66+
// )
67+
// }

0 commit comments

Comments
 (0)