Skip to content

Commit 4fd3209

Browse files
committed
leetcode
1 parent dd22a41 commit 4fd3209

File tree

4 files changed

+320
-1
lines changed

4 files changed

+320
-1
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
3+
-* 1443. Minimum Time to Collect All Apples in a Tree *-
4+
5+
6+
Given an undirected tree consisting of n vertices numbered from 0 to n-1, which has some apples in their vertices. You spend 1 second to walk over one edge of the tree. Return the minimum time in seconds you have to spend to collect all apples in the tree, starting at vertex 0 and coming back to this vertex.
7+
8+
The edges of the undirected tree are given in the array edges, where edges[i] = [ai, bi] means that exists an edge connecting the vertices ai and bi. Additionally, there is a boolean array hasApple, where hasApple[i] = true means that vertex i has an apple; otherwise, it does not have any apple.
9+
10+
11+
12+
Example 1:
13+
14+
15+
Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,true,false,true,true,false]
16+
Output: 8
17+
Explanation: The figure above represents the given tree where red vertices have an apple. One optimal path to collect all apples is shown by the green arrows.
18+
Example 2:
19+
20+
21+
Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,true,false,false,true,false]
22+
Output: 6
23+
Explanation: The figure above represents the given tree where red vertices have an apple. One optimal path to collect all apples is shown by the green arrows.
24+
Example 3:
25+
26+
Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,false,false,false,false,false]
27+
Output: 0
28+
29+
30+
Constraints:
31+
32+
1 <= n <= 105
33+
edges.length == n - 1
34+
edges[i].length == 2
35+
0 <= ai < bi <= n - 1
36+
from-i < toi
37+
hasApple.length == n
38+
39+
*/
40+
41+
import 'dart:collection';
42+
43+
class A {
44+
late int ans;
45+
int minTime(int n, List<List<int>> edges, List<bool> hasApple) {
46+
ans = 0;
47+
List<List<int>> a = List.filled(n, 0, growable: true)
48+
.map((e) => List.filled(n, 0, growable: true))
49+
.toList();
50+
for (int i = 0; i < n; i++) {
51+
a[i] = [];
52+
}
53+
for (List<int> arr in edges) {
54+
a[arr[0]].add(arr[1]);
55+
a[arr[1]].add(arr[0]);
56+
}
57+
List<bool> visited = List.filled(n, false);
58+
visited[0] = true;
59+
rec(n, a, hasApple, visited, 0);
60+
return ans;
61+
}
62+
63+
bool rec(int n, List<List<int>> a, List<bool> hasApple, List<bool> visited,
64+
int ind) {
65+
bool flag = false;
66+
for (int i = 0; i < a[ind].length; i++) {
67+
if (!visited[a[ind].elementAt(i)]) {
68+
visited[a[ind].elementAt(i)] = true;
69+
bool val = rec(n, a, hasApple, visited, a[ind].elementAt(i));
70+
if (val) {
71+
ans += 2;
72+
}
73+
flag = flag | val;
74+
}
75+
}
76+
flag = flag | hasApple.elementAt(ind);
77+
return flag;
78+
}
79+
}
80+
81+
class B {
82+
int res = 0;
83+
int minTime(int n, List<List<int>> edges, List<bool> hasApple) {
84+
HashMap<int, HashSet<int>> map = HashMap();
85+
for (List<int> edge in edges) {
86+
HashSet<int> list1 = map[edge[0]] ?? HashSet();
87+
HashSet<int> list2 = map[edge[1]] ?? HashSet();
88+
list1.add(edge[1]);
89+
list2.add(edge[0]);
90+
map.putIfAbsent(edge[0], () => list1);
91+
map.putIfAbsent(edge[1], () => list2);
92+
}
93+
List<bool> visited = List.filled(n, false);
94+
visited[0] = true;
95+
dfs(hasApple, map, 0, visited);
96+
return res;
97+
}
98+
99+
void dfs(List<bool> hasApple, HashMap<int, HashSet<int>> map, int index,
100+
List<bool> visited) {
101+
HashSet<int> list1 = map[index] ?? HashSet();
102+
for (int neighbor in list1) {
103+
if (!visited[neighbor]) {
104+
int temp = res;
105+
visited[neighbor] = true;
106+
if (hasApple[neighbor]) res += 2;
107+
dfs(hasApple, map, neighbor, visited);
108+
if (!hasApple[neighbor] && temp < res) {
109+
res += 2;
110+
}
111+
}
112+
}
113+
}
114+
}
115+
116+
class C {
117+
int minTime(int n, List<List<int>> edges, List<bool> hasApple) {
118+
HashMap<int, List<int>> map = HashMap();
119+
buildTree(edges, map);
120+
HashSet<int> visited = HashSet();
121+
return helper(0, map, hasApple, visited);
122+
}
123+
124+
void buildTree(List<List<int>> edges, HashMap<int, List<int>> map) {
125+
for (List<int> edge in edges) {
126+
int a = edge[0], b = edge[1];
127+
map.putIfAbsent(a, () => []);
128+
map.putIfAbsent(b, () => []);
129+
map[a]?.add(b);
130+
map[b]?.add(a);
131+
}
132+
}
133+
134+
int helper(int node, HashMap<int, List<int>> map, List<bool> hasApple,
135+
HashSet<int> visited) {
136+
visited.add(node);
137+
138+
int res = 0;
139+
140+
for (int child in map[node] ?? []) {
141+
if (visited.contains(child)) continue;
142+
res += helper(child, map, hasApple, visited);
143+
}
144+
145+
if ((res > 0 || hasApple[node]) && node != 0) res += 2;
146+
147+
return res;
148+
}
149+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package main
2+
3+
func minTime(n int, edges [][]int, hasApple []bool) int {
4+
graph := make([][]int, n)
5+
for _, edge := range edges {
6+
graph[edge[0]] = append(graph[edge[0]], edge[1])
7+
graph[edge[1]] = append(graph[edge[1]], edge[0])
8+
}
9+
10+
out := 0
11+
visited := make([]bool, n)
12+
visited[0] = true
13+
for _, node := range graph[0] {
14+
out += traverse(graph, node, hasApple, visited)
15+
}
16+
return out
17+
}
18+
19+
func traverse(graph [][]int, node int, hasApple []bool, visited []bool) int {
20+
out := 0
21+
visited[node] = true
22+
for _, n := range graph[node] {
23+
if !visited[n] {
24+
out += traverse(graph, n, hasApple, visited)
25+
}
26+
}
27+
if hasApple[node] || out != 0 {
28+
out += 2
29+
}
30+
return out
31+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# 🔥 3 Approaches 🔥 || Simple Fast and Easy || with Explanation
2+
3+
## Approach
4+
5+
Still need bi-direction graph and use visited set. Example test case for that:
6+
4
7+
[[0,2],[0,3],[1,2]]
8+
[false,true,false,false]
9+
Expected Answer: 4
10+
11+
Key Notes:
12+
13+
You need to consume 2 seconds to simply collect an apple node (come and go)
14+
Consider a node:
15+
If none of descendant (including itself) has an apple, we don't need to waste time on this node
16+
If any of descendant has an apple (no matter if it-self has an apple or not), we need to consume 2 seconds on this node anyway
17+
Collect node 0 does not need to consume any time
18+
Then, we can have a helper dfs function meaning: time needs to waste on this node to collect all apples. (0 or > 0).
19+
20+
## Solution - 1 Classic Depth First Search
21+
22+
```dart
23+
class Solution {
24+
int res = 0;
25+
int minTime(int n, List<List<int>> edges, List<bool> hasApple) {
26+
HashMap<int, HashSet<int>> map = HashMap();
27+
for (List<int> edge in edges) {
28+
HashSet<int> list1 = map[edge[0]] ?? HashSet();
29+
HashSet<int> list2 = map[edge[1]] ?? HashSet();
30+
list1.add(edge[1]);
31+
list2.add(edge[0]);
32+
map.putIfAbsent(edge[0], () => list1);
33+
map.putIfAbsent(edge[1], () => list2);
34+
}
35+
List<bool> visited = List.filled(n, false);
36+
visited[0] = true;
37+
dfs(hasApple, map, 0, visited);
38+
return res;
39+
}
40+
41+
void dfs(List<bool> hasApple, HashMap<int, HashSet<int>> map, int index,
42+
List<bool> visited) {
43+
HashSet<int> list1 = map[index] ?? HashSet();
44+
for (int neighbor in list1) {
45+
if (!visited[neighbor]) {
46+
int temp = res;
47+
visited[neighbor] = true;
48+
if (hasApple[neighbor]) res += 2;
49+
dfs(hasApple, map, neighbor, visited);
50+
if (!hasApple[neighbor] && temp < res) {
51+
res += 2;
52+
}
53+
}
54+
}
55+
}
56+
}
57+
```
58+
59+
## Solution - 2 Depth First Search - Via Building Tree
60+
61+
```dart
62+
class Solution {
63+
int minTime(int n, List<List<int>> edges, List<bool> hasApple) {
64+
HashMap<int, List<int>> map = HashMap();
65+
buildTree(edges, map);
66+
HashSet<int> visited = HashSet();
67+
return helper(0, map, hasApple, visited);
68+
}
69+
70+
void buildTree(List<List<int>> edges, HashMap<int, List<int>> map) {
71+
for (List<int> edge in edges) {
72+
int a = edge[0], b = edge[1];
73+
map.putIfAbsent(a, () => []);
74+
map.putIfAbsent(b, () => []);
75+
map[a]?.add(b);
76+
map[b]?.add(a);
77+
}
78+
}
79+
80+
int helper(int node, HashMap<int, List<int>> map, List<bool> hasApple,
81+
HashSet<int> visited) {
82+
visited.add(node);
83+
84+
int res = 0;
85+
86+
for (int child in map[node] ?? []) {
87+
if (visited.contains(child)) continue;
88+
res += helper(child, map, hasApple, visited);
89+
}
90+
91+
if ((res > 0 || hasApple[node]) && node != 0) res += 2;
92+
93+
return res;
94+
}
95+
}
96+
```
97+
98+
## Solution - 3 For FUN
99+
100+
```dart
101+
class Solution {
102+
late int ans;
103+
int minTime(int n, List<List<int>> edges, List<bool> hasApple) {
104+
ans = 0;
105+
List<List<int>> a = List.filled(n, 0, growable: true)
106+
.map((e) => List.filled(n, 0, growable: true))
107+
.toList();
108+
for (int i = 0; i < n; i++) {
109+
a[i] = [];
110+
}
111+
for (List<int> arr in edges) {
112+
a[arr[0]].add(arr[1]);
113+
a[arr[1]].add(arr[0]);
114+
}
115+
List<bool> visited = List.filled(n, false);
116+
visited[0] = true;
117+
rec(n, a, hasApple, visited, 0);
118+
return ans;
119+
}
120+
121+
bool rec(int n, List<List<int>> a, List<bool> hasApple, List<bool> visited,
122+
int ind) {
123+
bool flag = false;
124+
for (int i = 0; i < a[ind].length; i++) {
125+
if (!visited[a[ind].elementAt(i)]) {
126+
visited[a[ind].elementAt(i)] = true;
127+
bool val = rec(n, a, hasApple, visited, a[ind].elementAt(i));
128+
if (val) {
129+
ans += 2;
130+
}
131+
flag = flag | val;
132+
}
133+
}
134+
flag = flag | hasApple.elementAt(ind);
135+
return flag;
136+
}
137+
}
138+
```

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ This repo contain leetcode solution using DART and GO programming language. Most
170170
- [**1143.** Longest Common Subsequence](LongestCommonSubsequence/longest_common_subsequence.dart)
171171
- [**150.** Evaluate Reverse Polish Notation](EvaluateReversePolishNotation/evaluate_reverse_polish_notation.dart)
172172
- [**739.** Daily Temperatures](DailyTemperatures/daily_temperatures.dart)
173-
- [**1971.* Find if Path Exists in Graph](FindIfPathExistsInGraph/find_if_path_exists_in_graph.dart)
173+
- [**1971.** Find if Path Exists in Graph](FindIfPathExistsInGraph/find_if_path_exists_in_graph.dart)
174174
- [**841.** Keys and Rooms](KeysAndRooms/keys_and_rooms.dart)
175175
- [**886.** Possible Bipartition](PossibleBipartition/possible_bipartition.dart)
176176
- [**980.** Unique Paths III](UniquePathsIII/unique_paths_iii.dart)
@@ -180,6 +180,7 @@ This repo contain leetcode solution using DART and GO programming language. Most
180180
- [**452.** Minimum Number of Arrows to Burst Balloons](MinimumNumberOfArrowsToBurstBalloons/minimum_number_of_arrows_to_burst_balloons.dart)
181181
- [**1833.** Maximum Ice Cream Bars](MaximumIceCreamBars/maximum_ice_cream_bars.dart)
182182
- [**149.** Max Points on a Line](MaxPointsOnALine/max_points_on_a_line.dart)
183+
- [**1443.** Minimum Time to Collect All Apples in a Tree](MinimumTimeToCollectAllApplesInATree/minimum_time_to_collect_all_apples_in_a_tree.dart)
183184

184185
## Reach me via
185186

0 commit comments

Comments
 (0)