1. question: 加油站(中等)
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/gas-station
示例 1:
1 2 3 4 5 6 7 8 9 10
| 输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2] 输出: 3 解释: 从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油 开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油 开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油 开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油 开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油 开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。 因此,3 可为起始索引。
|
示例 2:
1 2 3 4 5 6 7 8 9
| 输入: gas = [2,3,4], cost = [3,4,3] 输出: -1 解释: 你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。 我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油 开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油 开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油 你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。 因此,无论怎样,你都不可能绕环路行驶一周。
|
提示:
1 2 3 4
| gas.length == n cost.length == n 1 <= n <= 105 0 <= gas[i], cost[i] <= 104
|
2. answers
这道题最开始想的是暴力法。模拟每个点作为起点,尝试模拟遍历流程,但是无论怎么优化还是超时。(未优化)代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| public class Solution_0100 {
public int canCompleteCircuit(int[] gas, int[] cost) {
int start = 0; boolean tag = false;
for (int i = 0; i < gas.length; i++) {
int remain = gas[i] - cost[i]; if(remain < 0) continue;
start = i; int index = start + 1;
index = index % gas.length;
while(index != start) {
remain = remain + gas[index] - cost[index];
if(remain < 0) { break; }
index ++;
index = index % gas.length; }
if(index == start) { tag = true; break; } }
return tag ? start : -1; }
public static void main(String[] args) { System.out.println();
int[] gas = {1,2,3,4,5}; int[] cost = {3,4,5,1,2};
Solution_0100 s = new Solution_0100();
System.out.println(s.canCompleteCircuit(gas, cost)); } }
|
参考题解,思路如下所示:
其实在模拟遍历的时候,如果从某个点i开始,累加,如果到达某个j时,出现了负数,就说明到达不了这个j点,也就到达不了循环。
那么其实[i, j]中的任何节点都到达不了。为什么呢?
- 首先[i, j]之间出现了负数,那么一定是[i, j-1]之间是正数,如果不是正数,那么肯定不会遍历到j点。
- 既然[i, j-1]是正数,那么[i, i+1]之间肯定是正数,[i+1, j-1]之间也是。
- 那么[i+1, j-1]之间的正数值,一定小于[i, j-1]的。既然i到达不了j,那么i+1肯定也到达不了j,更别提循环了。
其他节点同理。因此,当出现了遍历累加为负数时,中间的所有节点肯定都不是最终节点。只能从下个节点开始重新遍历。
代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| public class Solution_0100_03 {
public int canCompleteCircuit(int[] gas, int[] cost) {
int sums = 0; int start = 0; int index = 0; int count = 0;
while(start < gas.length) {
sums = sums + gas[index] - cost[index];
if(sums < 0) { start = start < index ? index + 1 : start + 1; count = 0; sums = 0; } else { count ++; }
index ++; index = index % gas.length;
if(count == gas.length) break; }
return count == gas.length ? start : -1; }
public static void main(String[] args) {
int[] gas = {1,2,3,4,5}; int[] cost = {3,4,5,1,2};
Solution_0100_03 s = new Solution_0100_03();
System.out.println(s.canCompleteCircuit(gas, cost)); } }
|
3. 备注
参考力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 (leetcode-cn.com),代码随想录 (programmercarl.com)。