一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
前言
力扣第134题 加油站
如下所示:
在一条环路上有 n
个加油站,其中第 i
个加油站有汽油 gas[i]
升。
你有一辆油箱容量无限的的汽车,从第 i
个加油站开往第 i+1
个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas
和 cost
,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1
。如果存在解,则 保证 它是 唯一 的。
一、思路
先简单梳理一下题目中的重点信息:
- 环形公路:表示第
n
个加油站的下一个为第1
个加油站 - 油箱容量无线:表示我们只需考虑消耗的汽油即可
- 如果存在解,则保证它们唯一:意思就是题目中有且仅有一个正确解
如果你刚开始看到第三点时,可能也会像我一样是蒙的。你反过来想一下,如果题目中的示例有多组解,那如何返回呢结果呢?题目也没说这种情况的处理方式,所以这个的意思就是只有一个正确解。
题目意思很明确,就是保证在有油的情况下,绕行公路一周。大致的步骤如下所示:
- 遍历每个加油站,作为起点
- 只要有油跑到下一个加油站,就一直向下跑
- 如果成功饶公路一圈,则返回起点(也是终点)的加油站
举个例子
示例一如下所示,红色数字部分为到下一个加油站所需要的油:
我们假设从 1号加油站
开始,很明显无法到达下一个加油站(1 < 3
)。同理从 2号加油站
也无法到达下一个加油站(2 < 4
)。3号加油站
作为起点也是无法到达下一个加油站。直到选择了 4号加油站
,才能够一致向下走,直到重新走到起点。
本来我以为这一题就这样轻松结束了,谁能想到会有下面这样的测试用例,导致我超时了。
为了解决这个问题,我们就需要将下一个加油站的起点设为上一次到不了的加油站。因为如果从 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);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~