题目描述
汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。
沿途有加油站,每个 station[i] 代表一个加油站,它位于出发位置东面 station[i][0] 英里处,并且有 station[i][1] 升汽油。
假设汽车油箱的容量是无限的,其中最初有 startFuel 升燃料。它每行驶 1 英里就会用掉 1 升汽油。
当汽车到达加油站时,汽车可以加油也可以继续行驶,如果能到达目的地则返回最少的加油次数,如果不能到达目的地则返回-1;
示例1:
输入:target = 100, startFuel = 25, stations = [[25, 25],[50, 25],[75, 25]]
输出:3
解释:(0,25)-------------(25,25)-------------(50,25)-------------(75,25)-------------(100,0)。汽车行驶25英里后,到达加油站加油25L(25英里);再行驶25英里后,到达加油站加油25L(50英里);再行驶25英里后,到达加油站加油25L(75英里);再行驶25英里后,到达目的地(100英里)
解法思路
1.贪心,根据汽车还有的燃料情况,把能经过的加油站统计出来;按照燃料树倒序排列,这里用到了PriorityQueue,通过PriorityQueue,能获取到最多的燃料。
2.如果发现燃料不够了,则从PriorityQueue取出最多的燃料,并将加油次数+1,如果已经充足则继续行驶,否则重复第2步操作。
3.简化代码逻辑,目的地作为特殊情况,可以作为一个 加油站,但是这个加油站没有油,来做计算。
代码实现
import java.util.Comparator;
import java.util.PriorityQueue;
class Solution1 {
public int minRefuelStops(int target, int startFuel, int[][] stations) {
if (stations.length <= 0 && startFuel < target) {
return -1;
}
if (startFuel >= target) {
return 0;
}
// 增加优先队列, 该方法使用了jdk 1.8
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
int count = 0;
int pre = 0;
int fuel = startFuel;
for (int i = 0; i <= stations.length; i++) {
int curr = (i >= stations.length ? target : stations[i][0]);
int distance = curr - pre;
fuel -= distance;
if (fuel >= 0 && i < stations.length) {
priorityQueue.offer(stations[i][1]);
} else {
while (fuel < 0 && !priorityQueue.isEmpty()) {
int oil = priorityQueue.poll();
fuel += oil;
count++;
}
if (fuel < 0) {
return -1;
} else if (i < stations.length) {
priorityQueue.offer(stations[i][1]);
}
}
if (i < stations.length) {
pre = stations[i][0];
}
}
return count;
}
public static void main(String[] args) {
Solution1 solution = new Solution1();
System.out.println(solution.minRefuelStops(100, 25, new int[][]{{25, 25}, {50, 25}, {75, 25}}));
}
}
总结
这个题看懂题目后,还是有一些思路的,重点就是通过贪心算法来获取最大的燃料数(这里用到了优先队列PriorityQueue)。