返回轨道
算法 · 2026-05-14 · 19 阅读

P196 加油站

算法 19 阅读

信号摘要

难度:Medium · 时长:13:24 · leetcode 134 · lintcode 187

P196 加油站

未对外公开播放权限
点击查看说明

描述

这个题目说的是,在一条环形公路上有 n 个加油站,编号是 0 ~ n-1。第 i 个加油站提供的油量是 gas[i],从第 i 个加油站开到第 i+1 个加油站需要的油量是 cost[i]。

给你一辆油箱容量无限大的汽车,并且一开始油箱为空。你要计算出,是否可以从某个加油站开始,顺时针绕环形公路一周。如果可以,返回出发加油站的编号;否则,返回 -1。

注意,给你的 gas 数组和 cost 数组都不为空,并且长度相同。另外,这个题目保证,要么不存在绕行公路一周的方案,要么就只有唯一一个出发点,可以绕行公路一周。

比如说,给你的 gas 数组和 cost 数组是:

gas: [1, 2, 4, 8] cost: [4, 8, 1, 2]

只要从编号为 2 的加油站开始,就可以顺利绕行公路一周:

// 到达 3 号加油站时的油量 0 + 4 - 1 = 3

// 到达 0 号加油站时的油量 3 + 8 - 2 = 9

// 到达 1 号加油站时的油量 9 + 1 - 4 = 6

// 回到 2 号加油站时的油量 6 + 2 - 8 = 0

这样就从 2 号加油站出发,顺利绕行一周,回到 2 号加油站。因此你要返回的出发加油站编号就是 2。

代码

public class AlgoCasts {

  // Time: O(n^2), Space: O(1)
  public int canCompleteCircuitBruteForce(int[] gas, int[] cost) {
    int n = gas.length;
    for (int i = 0; i < n; ++i) {
      int tank = 0;
      for (int j = i; j < i+n; ++j) {
        int k = j % n;
        tank += gas[k] - cost[k];
        if (tank < 0) break;
      }
      if (tank >= 0) return i;
    }
    return -1;
  }

  // Time: O(n), Space: O(1)
  public int canCompleteCircuitSkip(int[] gas, int[] cost) {
    int n = gas.length, j = 0;
    for (int i = 0; i < n; i = j+1) {
      int tank = 0;
      for (j = i; j < i+n; ++j) {
        int k = j % n;
        tank += gas[k] - cost[k];
        if (tank < 0) break;
      }
      if (tank >= 0) return i;
    }
    return -1;
  }

  // Time: O(n), Space: O(1)
  public int canCompleteCircuitGreedy(int[] gas, int[] cost) {
    int n = gas.length, start = 0;
    int total = 0, tank = 0;
    for (int i = 0; i < n; ++i) {
      total += gas[i] - cost[i];
      tank += gas[i] - cost[i];
      if (tank < 0) {
        start = i + 1;
        tank = 0;
      }
    }
    return total < 0 ? -1 : start;
  }

}

📡 通讯频道