力扣第134题-加油站

238 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

前言

力扣第134题 加油站 如下所示:

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

image.png

一、思路

先简单梳理一下题目中的重点信息:

  1. 环形公路:表示第 n 个加油站的下一个为第 1 个加油站
  2. 油箱容量无线:表示我们只需考虑消耗的汽油即可
  3. 如果存在解,则保证它们唯一:意思就是题目中有且仅有一个正确解

如果你刚开始看到第三点时,可能也会像我一样是蒙的。你反过来想一下,如果题目中的示例有多组解,那如何返回呢结果呢?题目也没说这种情况的处理方式,所以这个的意思就是只有一个正确解。

题目意思很明确,就是保证在有油的情况下,绕行公路一周。大致的步骤如下所示:

  1. 遍历每个加油站,作为起点
  2. 只要有油跑到下一个加油站,就一直向下跑
  3. 如果成功饶公路一圈,则返回起点(也是终点)的加油站

举个例子

示例一如下所示,红色数字部分为到下一个加油站所需要的油:

image.png

我们假设从 1号加油站开始,很明显无法到达下一个加油站(1 < 3)。同理从 2号加油站 也无法到达下一个加油站(2 < 4)。3号加油站 作为起点也是无法到达下一个加油站。直到选择了 4号加油站,才能够一致向下走,直到重新走到起点。

image.png

本来我以为这一题就这样轻松结束了,谁能想到会有下面这样的测试用例,导致我超时了。

image.png

为了解决这个问题,我们就需要将下一个加油站的起点设为上一次到不了的加油站。因为如果从 i 出发到不了 j,你无论从i ~ j 的任何一个位置出发还是到不了 j

二、实现

实现代码

实现代码比较简单,只需要两层遍历即可找到正确的起点。

public int canCompleteCircuit(int[] gas, int[] cost) {
    int n = gas.length;
    for (int i=0; i<n; i++){
        int left = 0;   // 剩下的油
        int j=0;
        for (; j<n; j++){
            int c = (i + j) % n;
            left += gas[c] - cost[c];
            if (left < 0)
                break;
        }
        if (j == n)   // 跑了一圈
            return i;
        else
            i = i + j;
    }
    return -1;
}

测试代码

public static void main(String[] args) {
    int[] nums1 = {1,2,3,4,5};
    int[] nums2 = {3,4,5,1,2};
    int ret = new Number134().canCompleteCircuit(nums1, nums2);
    System.out.println(ret);

}

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~