当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度:
Hard

题意:

  1. 一辆车要从start跑到target,带着fuel单位的油
  2. 中间有很多个加油站,给定加油站的坐标和油量。到了加油站你可以选择到站加油和直接过站
  3. 求最少需要停几个加油站

思路:

  • 看起来是不是跟403的Frog jump很像啊,看数据范围,确实也是个动态规划的题目,动态规划的解法留给大家做,这里说一个更简单的方法
  • 我们可以换种思路。每次到站之后,把所有加油站的油都带上。先不加,等到有需要的时候再加。如果发现不够油到下个加油站,那么我们就优先选择油多的加油站的油来加,相当于我们在那个加油站停了。这里为什么优先选择油多的加油站呢?因为油多也是一站,油少也是一站。
  • 如果把所有的油加满都达不到下个加油站,那么,输出-1
  • 如果可以到target之后,我们就输出加了多少个加油站的油即可
  • 中间那部分,优先选择油多,我们需要维护一个优先队列(即最大堆),复杂度o(nlogn),当然按照数据范围,就算是用一个链表啊,数组啊,o(n^2)照样能过,这道题的数据范围出错了,应该是stations.length<=100000
  • 这种算法叫贪心

代码:

  1. class Solution {
  2. private int runTo(int start, int fuel, int target, PriorityQueue<Integer> queue) {
  3. fuel -= target - start;
  4. while (fuel < 0) {
  5. Integer top = queue.poll();
  6. if (top == null) {
  7. return -1;
  8. }
  9. fuel += top;
  10. }
  11. return fuel;
  12. }
  13. public int minRefuelStops(int target, int startFuel, int[][] stations) {
  14. PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
  15. @Override
  16. public int compare(Integer o1, Integer o2) {
  17. return -Integer.compare(o1, o2);
  18. }
  19. });
  20. int start = 0;
  21. int fuel = startFuel;
  22. for (int i = 0;i < stations.length;i++) {
  23. fuel = runTo(start, fuel, stations[i][0], queue);
  24. if (fuel == -1) {
  25. return fuel;
  26. }
  27. queue.add(stations[i][1]);
  28. start = stations[i][0];
  29. }
  30. if (runTo(start, fuel, target, queue) != -1) {
  31. return stations.length - queue.size();
  32. } else {
  33. return -1;
  34. }
  35. }
  36. }

该分类下的相关小册推荐: