LeetCode 871. Minimum Number of Refueling Stops - 优先级队列(Priority Queue)系列题8

A car travels from a starting position to a destination which is target miles east of the starting position.

There are gas stations along the way. The gas stations are represented as an array stations where stations[i] = [positioni, fueli] indicates that the ith gas station is positioni miles east of the starting position and has fueli liters of gas.

The car starts with an infinite tank of gas, which initially has startFuel liters of fuel in it. It uses one liter of gas per one mile that it drives. When the car reaches a gas station, it may stop and refuel, transferring all the gas from the station into the car.

Return the minimum number of refueling stops the car must make in order to reach its destination. If it cannot reach the destination, return -1.

Note that if the car reaches a gas station with 0 fuel left, the car can still refuel there. If the car reaches the destination with 0 fuel left, it is still considered to have arrived.

Example 1:

Input: target = 1, startFuel = 1, stations = []
Output: 0
Explanation: We can reach the target without refueling.

Example 2:

Input: target = 100, startFuel = 1, stations = [[10,100]]
Output: -1
Explanation: We can not reach the target (or even the first gas station).

Example 3:

Input: target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]
Output: 2
Explanation: We start with 10 liters of fuel.
We drive to position 10, expending 10 liters of fuel.  We refuel from 0 liters to 60 liters of gas.
Then, we drive from position 10 to position 60 (expending 50 liters of fuel),
and refuel from 10 liters to 50 liters of gas.  We then drive to and reach the target.
We made 2 refueling stops along the way, so we return 2.

Constraints:

  • 1 <= target, startFuel <= 109
  • 0 <= stations.length <= 500
  • 0 <= positioni <= positioni+1 < target
  • 1 <= fueli < 109

题目大意是一辆车要从出发点一路向东开到目的地, 目的地在起点以东target英里处。沿途有一系列加油站用一个数组stations表示,stations[i] = [positioni, fueli]表示第i个加油站离起点positioni英里,有fueli公升的汽油。假设汽车有一个无限大的油箱,在起点处拥有startFuel升的汽油,耗油量每英里一升油。当汽车经过一个加油站,它可以选择停下来把加油站的所有油加入油箱,然后继续前行。问最少需要加油几次可以使汽车到达目的地,如果无论如何都到达不了就返回-1。

解题思路:为了达到加油次数最少,可以先尽量让汽车用现有的油一直往前开沿途都不停下加油,如果能一路开到目的地那最好,如果在中途某一站发现所剩油量不足以到达下一站,这说明汽车在前面经过的加油站至少要停下加油一次,本着贪心法则自然是从储油量从多到少的加油站开始加,只要加到能保证汽车至少能到达下一站就让汽车继续前行直到下次油量不够,再从经过的加油站中从多到少地加油(之前已经被加过油的站已经没有油了需要被排除),就这样反复进行直到汽车到达目的地。要是在某一次把经过的所有站的油都加了也无法到达下一站,那说明无论如何也到达不了目的地。

由于每次都是先不加油让汽车一直往前开,直到油量不够才停下选择油最多的站来加油,因此可以用一个优先级队列(最大堆)来存储经过的加油站的油量,每次需要加油时从优先级队列中弹出的顺序就是油量从多到少的顺序。

class Solution:
    def minRefuelStops(self, target: int, startFuel: int, stations: List[List[int]]) -> int:
        res = 0
        totalFuel = startFuel
        
        pq = []
        dist = 0
        for s in stations:
            totalFuel -= s[0] - dist
            while pq and totalFuel < 0:
                totalFuel -= heapq.heappop(pq)
                res += 1
            
            if totalFuel < 0:
                return -1
            
            heapq.heappush(pq, -s[1])
            dist = s[0]
        
        totalFuel -= target - dist
        while pq and totalFuel < 0:
            totalFuel -= heapq.heappop(pq)
            res += 1
        
        return res if totalFuel >= 0 else -1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值