79
79
80
80
### 方法一:贪心 + 优先队列(大根堆)
81
81
82
- 利用优先队列记录所有已经到达过的加油站的加油量 ,每次当油量不足时,从队列中取出最大加油量, 并累计加油次数 ans。
82
+ 我们可以利用优先队列(大根堆) $\textit{pq}$ 记录所有已经到达过的加油站的加油量 ,每次当油量不足时,贪心地取出最大加油量,即 $\textit{pq}$ 的堆顶元素, 并累计加油次数 $\textit{ ans}$。如果 $\textit{pq}$ 为空并且当前油量仍然不足,说明无法到达目的地,返回 $-1$ 。
83
83
84
- 时间复杂度 $O(nlogn)$ 。其中 $n$ 表示数组 ` stations ` 的长度 。
84
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$ 。其中 $n$ 表示加油站的数量 。
85
85
86
86
<!-- tabs:start -->
87
87
@@ -92,19 +92,19 @@ class Solution:
92
92
def minRefuelStops (
93
93
self , target : int , startFuel : int , stations : List[List[int ]]
94
94
) -> int :
95
- q = []
96
- prev = ans = 0
95
+ pq = []
96
+ ans = pre = 0
97
97
stations.append([target, 0 ])
98
- for a, b in stations:
99
- d = a - prev
100
- startFuel -= d
101
- while startFuel < 0 and q :
102
- startFuel -= heappop(q )
98
+ for pos, fuel in stations:
99
+ dist = pos - pre
100
+ startFuel -= dist
101
+ while startFuel < 0 and pq :
102
+ startFuel -= heappop(pq )
103
103
ans += 1
104
104
if startFuel < 0 :
105
105
return - 1
106
- heappush(q , - b )
107
- prev = a
106
+ heappush(pq , - fuel )
107
+ pre = pos
108
108
return ans
109
109
```
110
110
@@ -113,22 +113,23 @@ class Solution:
113
113
``` java
114
114
class Solution {
115
115
public int minRefuelStops (int target , int startFuel , int [][] stations ) {
116
- PriorityQueue<Integer > q = new PriorityQueue<> ((a, b) - > b - a);
116
+ PriorityQueue<Integer > pq = new PriorityQueue<> ((a, b) - > b - a);
117
117
int n = stations. length;
118
- int prev = 0 , ans = 0 ;
119
- for (int i = 0 ; i < n + 1 ; ++ i) {
120
- int d = (i < n ? stations[i][0 ] : target) - prev;
121
- startFuel -= d;
122
- while (startFuel < 0 && ! q. isEmpty()) {
123
- startFuel += q. poll();
118
+ int ans = 0 , pre = 0 ;
119
+ for (int i = 0 ; i <= n; ++ i) {
120
+ int pos = i < n ? stations[i][0 ] : target;
121
+ int dist = pos - pre;
122
+ startFuel -= dist;
123
+ while (startFuel < 0 && ! pq. isEmpty()) {
124
+ startFuel += pq. poll();
124
125
++ ans;
125
126
}
126
127
if (startFuel < 0 ) {
127
128
return - 1 ;
128
129
}
129
130
if (i < n) {
130
- q . offer(stations[i][1 ]);
131
- prev = stations[i][0 ];
131
+ pq . offer(stations[i][1 ]);
132
+ pre = stations[i][0 ];
132
133
}
133
134
}
134
135
return ans;
@@ -142,20 +143,23 @@ class Solution {
142
143
class Solution {
143
144
public:
144
145
int minRefuelStops(int target, int startFuel, vector<vector<int >>& stations) {
145
- priority_queue<int > q ;
146
+ priority_queue<int > pq ;
146
147
stations.push_back({target, 0});
147
- int ans = 0, prev = 0;
148
- for (auto& s : stations) {
149
- int d = s[ 0] - prev;
150
- startFuel -= d;
151
- while (startFuel < 0 && !q.empty()) {
152
- startFuel += q.top();
153
- q.pop();
148
+ int ans = 0, pre = 0;
149
+ for (const auto& station : stations) {
150
+ int pos = station[ 0] , fuel = station[ 1] ;
151
+ int dist = pos - pre;
152
+ startFuel -= dist;
153
+ while (startFuel < 0 && !pq.empty()) {
154
+ startFuel += pq.top();
155
+ pq.pop();
154
156
++ans;
155
157
}
156
- if (startFuel < 0) return -1;
157
- q.push(s[ 1] );
158
- prev = s[ 0] ;
158
+ if (startFuel < 0) {
159
+ return -1;
160
+ }
161
+ pq.push(fuel);
162
+ pre = pos;
159
163
}
160
164
return ans;
161
165
}
@@ -166,22 +170,22 @@ public:
166
170
167
171
```go
168
172
func minRefuelStops(target int, startFuel int, stations [][]int) int {
173
+ pq := &hp{}
174
+ ans, pre := 0, 0
169
175
stations = append(stations, []int{target, 0})
170
- ans, prev := 0, 0
171
- q := &hp{}
172
- heap.Init(q)
173
- for _, s := range stations {
174
- d := s[0] - prev
175
- startFuel -= d
176
- for startFuel < 0 && q.Len() > 0 {
177
- startFuel += q.pop()
176
+ for _, station := range stations {
177
+ pos, fuel := station[0], station[1]
178
+ dist := pos - pre
179
+ startFuel -= dist
180
+ for startFuel < 0 && pq.Len() > 0 {
181
+ startFuel += heap.Pop(pq).(int)
178
182
ans++
179
183
}
180
184
if startFuel < 0 {
181
185
return -1
182
186
}
183
- q.push(s[1] )
184
- prev = s[0]
187
+ heap.Push(pq, fuel )
188
+ pre = pos
185
189
}
186
190
return ans
187
191
}
@@ -196,8 +200,67 @@ func (h *hp) Pop() any {
196
200
h.IntSlice = a[:len(a)-1]
197
201
return v
198
202
}
199
- func (h *hp) push(v int) { heap.Push(h, v) }
200
- func (h *hp) pop() int { return heap.Pop(h).(int) }
203
+ ```
204
+
205
+ #### TypeScript
206
+
207
+ ``` ts
208
+ function minRefuelStops(target : number , startFuel : number , stations : number [][]): number {
209
+ const pq = new MaxPriorityQueue ();
210
+ let [ans, pre] = [0 , 0 ];
211
+ stations .push ([target , 0 ]);
212
+ for (const [pos, fuel] of stations ) {
213
+ const dist = pos - pre ;
214
+ startFuel -= dist ;
215
+ while (startFuel < 0 && ! pq .isEmpty ()) {
216
+ startFuel += pq .dequeue ().element ;
217
+ ans ++ ;
218
+ }
219
+ if (startFuel < 0 ) {
220
+ return - 1 ;
221
+ }
222
+ pq .enqueue (fuel );
223
+ pre = pos ;
224
+ }
225
+ return ans ;
226
+ }
227
+ ```
228
+
229
+ #### Rust
230
+
231
+ ``` rust
232
+ use std :: collections :: BinaryHeap ;
233
+
234
+ impl Solution {
235
+ pub fn min_refuel_stops (target : i32 , mut start_fuel : i32 , mut stations : Vec <Vec <i32 >>) -> i32 {
236
+ let mut pq = BinaryHeap :: new ();
237
+ let mut ans = 0 ;
238
+ let mut pre = 0 ;
239
+
240
+ stations . push (vec! [target , 0 ]);
241
+
242
+ for station in stations {
243
+ let pos = station [0 ];
244
+ let fuel = station [1 ];
245
+ let dist = pos - pre ;
246
+ start_fuel -= dist ;
247
+
248
+ while start_fuel < 0 && ! pq . is_empty () {
249
+ start_fuel += pq . pop (). unwrap ();
250
+ ans += 1 ;
251
+ }
252
+
253
+ if start_fuel < 0 {
254
+ return - 1 ;
255
+ }
256
+
257
+ pq . push (fuel );
258
+ pre = pos ;
259
+ }
260
+
261
+ ans
262
+ }
263
+ }
201
264
```
202
265
203
266
<!-- tabs: end -->
0 commit comments