Skip to content

Commit 18de759

Browse files
authored
feat: add solutions to lc problem: No.0871 (#3605)
No.0871.Minimum Number of Refueling Stops
1 parent 69d670b commit 18de759

File tree

8 files changed

+311
-128
lines changed

8 files changed

+311
-128
lines changed

solution/0800-0899/0871.Minimum Number of Refueling Stops/README.md

Lines changed: 106 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ tags:
7979

8080
### 方法一:贪心 + 优先队列(大根堆)
8181

82-
利用优先队列记录所有已经到达过的加油站的加油量,每次当油量不足时,从队列中取出最大加油量,并累计加油次数 ans。
82+
我们可以利用优先队列(大根堆) $\textit{pq}$ 记录所有已经到达过的加油站的加油量,每次当油量不足时,贪心地取出最大加油量,即 $\textit{pq}$ 的堆顶元素,并累计加油次数 $\textit{ans}$。如果 $\textit{pq}$ 为空并且当前油量仍然不足,说明无法到达目的地,返回 $-1$
8383

84-
时间复杂度 $O(nlogn)$。其中 $n$ 表示数组 `stations` 的长度
84+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 表示加油站的数量
8585

8686
<!-- tabs:start -->
8787

@@ -92,19 +92,19 @@ class Solution:
9292
def minRefuelStops(
9393
self, target: int, startFuel: int, stations: List[List[int]]
9494
) -> int:
95-
q = []
96-
prev = ans = 0
95+
pq = []
96+
ans = pre = 0
9797
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)
103103
ans += 1
104104
if startFuel < 0:
105105
return -1
106-
heappush(q, -b)
107-
prev = a
106+
heappush(pq, -fuel)
107+
pre = pos
108108
return ans
109109
```
110110

@@ -113,22 +113,23 @@ class Solution:
113113
```java
114114
class Solution {
115115
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);
117117
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();
124125
++ans;
125126
}
126127
if (startFuel < 0) {
127128
return -1;
128129
}
129130
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];
132133
}
133134
}
134135
return ans;
@@ -142,20 +143,23 @@ class Solution {
142143
class Solution {
143144
public:
144145
int minRefuelStops(int target, int startFuel, vector<vector<int>>& stations) {
145-
priority_queue<int> q;
146+
priority_queue<int> pq;
146147
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();
154156
++ans;
155157
}
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;
159163
}
160164
return ans;
161165
}
@@ -166,22 +170,22 @@ public:
166170
167171
```go
168172
func minRefuelStops(target int, startFuel int, stations [][]int) int {
173+
pq := &hp{}
174+
ans, pre := 0, 0
169175
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)
178182
ans++
179183
}
180184
if startFuel < 0 {
181185
return -1
182186
}
183-
q.push(s[1])
184-
prev = s[0]
187+
heap.Push(pq, fuel)
188+
pre = pos
185189
}
186190
return ans
187191
}
@@ -196,8 +200,67 @@ func (h *hp) Pop() any {
196200
h.IntSlice = a[:len(a)-1]
197201
return v
198202
}
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+
}
201264
```
202265

203266
<!-- tabs:end -->

0 commit comments

Comments
 (0)