Skip to content

Commit 3a83873

Browse files
authored
Merge pull request #3
* feat: add minTime solutions in Python, C++, and Go for LC problem #3604
1 parent 80bf294 commit 3a83873

File tree

5 files changed

+465
-6
lines changed

5 files changed

+465
-6
lines changed

solution/3600-3699/3604.Minimum Time to Reach Destination in Directed Graph/README.md

Lines changed: 155 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,29 @@ tags:
118118
#### Python3
119119

120120
```python
121-
121+
class Solution:
122+
def minTime(self, n: int, edges: List[List[int]]) -> int:
123+
minReachTime = [inf] * n
124+
minReachTime[0] = 0
125+
126+
nodeEdges = [[] for _ in range(n)]
127+
for edge in edges:
128+
nodeEdges[edge[0]].append(edge)
129+
130+
reachTimeHeap = [(0, 0)]
131+
while reachTimeHeap:
132+
curTime, node = heappop(reachTimeHeap)
133+
if node == n - 1:
134+
return curTime
135+
136+
for edge in nodeEdges[node]:
137+
if curTime <= edge[3]:
138+
destTime = max(curTime, edge[2]) + 1
139+
if minReachTime[edge[1]] > destTime:
140+
minReachTime[edge[1]] = destTime
141+
heappush(reachTimeHeap, (destTime, edge[1]))
142+
143+
return -1
122144
```
123145

124146
#### Java
@@ -130,13 +152,143 @@ tags:
130152
#### C++
131153

132154
```cpp
133-
155+
class Solution {
156+
vector<vector<vector<int>>> adj;
157+
vector<int> sol;
158+
priority_queue<pair<int,int> ,vector<pair<int,int>>,greater<>> pq;
159+
void pushNeighbours(int node,int curr){
160+
for(auto it : adj[node]){
161+
int temp = it[0] , start = it[1],end = it[2],newTime = curr+1;
162+
if(curr<start) newTime = start+1;
163+
if(newTime < sol[temp] && newTime-1<=end){
164+
pq.push({newTime,temp});
165+
sol[temp] = newTime;
166+
}
167+
}
168+
}
169+
public:
170+
int minTime(int n, vector<vector<int>>& edges) {
171+
adj = vector<vector<vector<int>>>(n);
172+
for(auto it: edges)
173+
adj[it[0]].push_back({it[1],it[2],it[3]});
174+
sol = vector<int> (n,INT_MAX);
175+
sol[0]=0;
176+
for(pq.push({0,0});!pq.empty();pq.pop())
177+
pushNeighbours(pq.top().second,pq.top().first);
178+
if(sol[n-1] == INT_MAX) return -1;
179+
return sol[n-1];
180+
}
181+
};
182+
const auto __ = []() {
183+
struct ___ {
184+
static void _() {
185+
std::ofstream("display_runtime.txt") << 0 << '\n';
186+
std::ofstream("display_memory.txt") << 0 << '\n';
187+
}
188+
};
189+
std::atexit(&___::_);
190+
return 0;
191+
}();
134192
```
135193
136194
#### Go
137195
138196
```go
139-
197+
import "container/heap"
198+
199+
func minTime(n int, edges [][]int) int {
200+
graph := make([][][3]int, n)
201+
for _, edge := range edges {
202+
u, v, start, end := edge[0], edge[1], edge[2], edge[3]
203+
graph[u] = append(graph[u], [3]int{v, start, end})
204+
}
205+
206+
dist := make([]int, n)
207+
for i := range dist {
208+
dist[i] = -1
209+
}
210+
dist[0] = 0
211+
212+
pq := &PriorityQueue{}
213+
heap.Init(pq)
214+
heap.Push(pq, &Item{value: 0, priority: 0})
215+
216+
for pq.Len() > 0 {
217+
item := heap.Pop(pq).(*Item)
218+
u := item.value
219+
d := item.priority
220+
221+
if d > dist[u] && dist[u] != -1{
222+
continue
223+
}
224+
225+
226+
if u == n-1{
227+
continue
228+
}
229+
230+
231+
for _, edge := range graph[u] {
232+
v, start, end := edge[0], edge[1], edge[2]
233+
234+
wait := 0
235+
if d < start {
236+
wait = start - d
237+
}
238+
239+
if d + wait <= end {
240+
newDist := d + wait + 1
241+
if dist[v] == -1 || newDist < dist[v] {
242+
dist[v] = newDist
243+
heap.Push(pq, &Item{value: v, priority: newDist})
244+
}
245+
}
246+
}
247+
}
248+
249+
return dist[n-1]
250+
}
251+
252+
type Item struct {
253+
value int // The value of the item; arbitrary.
254+
priority int // The priority of the item in the queue.
255+
// The index is needed to update during heap operations. It is
256+
// maintained by the heap.Interface methods.
257+
index int // The index of the item in the heap.
258+
}
259+
260+
// A PriorityQueue implements heap.Interface and holds Items.
261+
type PriorityQueue []*Item
262+
263+
func (pq PriorityQueue) Len() int { return len(pq) }
264+
265+
func (pq PriorityQueue) Less(i, j int) bool {
266+
// We want Pop to give us the lowest, not highest, priority so we use less than here.
267+
return pq[i].priority < pq[j].priority
268+
}
269+
270+
func (pq PriorityQueue) Swap(i, j int) {
271+
pq[i], pq[j] = pq[j], pq[i]
272+
pq[i].index = i
273+
pq[j].index = j
274+
}
275+
276+
func (pq *PriorityQueue) Push(x any) {
277+
n := len(*pq)
278+
item := x.(*Item)
279+
item.index = n
280+
*pq = append(*pq, item)
281+
}
282+
283+
func (pq *PriorityQueue) Pop() any {
284+
old := *pq
285+
n := len(old)
286+
item := old[n-1]
287+
old[n-1] = nil // avoid memory leak
288+
item.index = -1 // for safety
289+
*pq = old[0 : n-1]
290+
return item
291+
}
140292
```
141293

142294
<!-- tabs:end -->

solution/3600-3699/3604.Minimum Time to Reach Destination in Directed Graph/README_EN.md

Lines changed: 155 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,29 @@ tags:
115115
#### Python3
116116

117117
```python
118-
118+
class Solution:
119+
def minTime(self, n: int, edges: List[List[int]]) -> int:
120+
minReachTime = [inf] * n
121+
minReachTime[0] = 0
122+
123+
nodeEdges = [[] for _ in range(n)]
124+
for edge in edges:
125+
nodeEdges[edge[0]].append(edge)
126+
127+
reachTimeHeap = [(0, 0)]
128+
while reachTimeHeap:
129+
curTime, node = heappop(reachTimeHeap)
130+
if node == n - 1:
131+
return curTime
132+
133+
for edge in nodeEdges[node]:
134+
if curTime <= edge[3]:
135+
destTime = max(curTime, edge[2]) + 1
136+
if minReachTime[edge[1]] > destTime:
137+
minReachTime[edge[1]] = destTime
138+
heappush(reachTimeHeap, (destTime, edge[1]))
139+
140+
return -1
119141
```
120142

121143
#### Java
@@ -127,13 +149,143 @@ tags:
127149
#### C++
128150

129151
```cpp
130-
152+
class Solution {
153+
vector<vector<vector<int>>> adj;
154+
vector<int> sol;
155+
priority_queue<pair<int,int> ,vector<pair<int,int>>,greater<>> pq;
156+
void pushNeighbours(int node,int curr){
157+
for(auto it : adj[node]){
158+
int temp = it[0] , start = it[1],end = it[2],newTime = curr+1;
159+
if(curr<start) newTime = start+1;
160+
if(newTime < sol[temp] && newTime-1<=end){
161+
pq.push({newTime,temp});
162+
sol[temp] = newTime;
163+
}
164+
}
165+
}
166+
public:
167+
int minTime(int n, vector<vector<int>>& edges) {
168+
adj = vector<vector<vector<int>>>(n);
169+
for(auto it: edges)
170+
adj[it[0]].push_back({it[1],it[2],it[3]});
171+
sol = vector<int> (n,INT_MAX);
172+
sol[0]=0;
173+
for(pq.push({0,0});!pq.empty();pq.pop())
174+
pushNeighbours(pq.top().second,pq.top().first);
175+
if(sol[n-1] == INT_MAX) return -1;
176+
return sol[n-1];
177+
}
178+
};
179+
const auto __ = []() {
180+
struct ___ {
181+
static void _() {
182+
std::ofstream("display_runtime.txt") << 0 << '\n';
183+
std::ofstream("display_memory.txt") << 0 << '\n';
184+
}
185+
};
186+
std::atexit(&___::_);
187+
return 0;
188+
}();
131189
```
132190
133191
#### Go
134192
135193
```go
136-
194+
import "container/heap"
195+
196+
func minTime(n int, edges [][]int) int {
197+
graph := make([][][3]int, n)
198+
for _, edge := range edges {
199+
u, v, start, end := edge[0], edge[1], edge[2], edge[3]
200+
graph[u] = append(graph[u], [3]int{v, start, end})
201+
}
202+
203+
dist := make([]int, n)
204+
for i := range dist {
205+
dist[i] = -1
206+
}
207+
dist[0] = 0
208+
209+
pq := &PriorityQueue{}
210+
heap.Init(pq)
211+
heap.Push(pq, &Item{value: 0, priority: 0})
212+
213+
for pq.Len() > 0 {
214+
item := heap.Pop(pq).(*Item)
215+
u := item.value
216+
d := item.priority
217+
218+
if d > dist[u] && dist[u] != -1{
219+
continue
220+
}
221+
222+
223+
if u == n-1{
224+
continue
225+
}
226+
227+
228+
for _, edge := range graph[u] {
229+
v, start, end := edge[0], edge[1], edge[2]
230+
231+
wait := 0
232+
if d < start {
233+
wait = start - d
234+
}
235+
236+
if d + wait <= end {
237+
newDist := d + wait + 1
238+
if dist[v] == -1 || newDist < dist[v] {
239+
dist[v] = newDist
240+
heap.Push(pq, &Item{value: v, priority: newDist})
241+
}
242+
}
243+
}
244+
}
245+
246+
return dist[n-1]
247+
}
248+
249+
type Item struct {
250+
value int // The value of the item; arbitrary.
251+
priority int // The priority of the item in the queue.
252+
// The index is needed to update during heap operations. It is
253+
// maintained by the heap.Interface methods.
254+
index int // The index of the item in the heap.
255+
}
256+
257+
// A PriorityQueue implements heap.Interface and holds Items.
258+
type PriorityQueue []*Item
259+
260+
func (pq PriorityQueue) Len() int { return len(pq) }
261+
262+
func (pq PriorityQueue) Less(i, j int) bool {
263+
// We want Pop to give us the lowest, not highest, priority so we use less than here.
264+
return pq[i].priority < pq[j].priority
265+
}
266+
267+
func (pq PriorityQueue) Swap(i, j int) {
268+
pq[i], pq[j] = pq[j], pq[i]
269+
pq[i].index = i
270+
pq[j].index = j
271+
}
272+
273+
func (pq *PriorityQueue) Push(x any) {
274+
n := len(*pq)
275+
item := x.(*Item)
276+
item.index = n
277+
*pq = append(*pq, item)
278+
}
279+
280+
func (pq *PriorityQueue) Pop() any {
281+
old := *pq
282+
n := len(old)
283+
item := old[n-1]
284+
old[n-1] = nil // avoid memory leak
285+
item.index = -1 // for safety
286+
*pq = old[0 : n-1]
287+
return item
288+
}
137289
```
138290

139291
<!-- tabs:end -->
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Solution {
2+
vector<vector<vector<int>>> adj;
3+
vector<int> sol;
4+
priority_queue<pair<int,int> ,vector<pair<int,int>>,greater<>> pq;
5+
void pushNeighbours(int node,int curr){
6+
for(auto it : adj[node]){
7+
int temp = it[0] , start = it[1],end = it[2],newTime = curr+1;
8+
if(curr<start) newTime = start+1;
9+
if(newTime < sol[temp] && newTime-1<=end){
10+
pq.push({newTime,temp});
11+
sol[temp] = newTime;
12+
}
13+
}
14+
}
15+
public:
16+
int minTime(int n, vector<vector<int>>& edges) {
17+
adj = vector<vector<vector<int>>>(n);
18+
for(auto it: edges)
19+
adj[it[0]].push_back({it[1],it[2],it[3]});
20+
sol = vector<int> (n,INT_MAX);
21+
sol[0]=0;
22+
for(pq.push({0,0});!pq.empty();pq.pop())
23+
pushNeighbours(pq.top().second,pq.top().first);
24+
if(sol[n-1] == INT_MAX) return -1;
25+
return sol[n-1];
26+
}
27+
};
28+
const auto __ = []() {
29+
struct ___ {
30+
static void _() {
31+
std::ofstream("display_runtime.txt") << 0 << '\n';
32+
std::ofstream("display_memory.txt") << 0 << '\n';
33+
}
34+
};
35+
std::atexit(&___::_);
36+
return 0;
37+
}();

0 commit comments

Comments
 (0)