在一条环路上有 n
个加油站,其中第 i
个加油站有汽油 gas[i]
升。
你有一辆油箱容量无限的的汽车,从第 i
个加油站开往第 i+1
个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas
和 cost
,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1
。如果存在解,则 保证 它是 唯一 的。
输入: 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 可为起始索引。
输入: 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 升汽油。 因此,无论怎样,你都不可能绕环路行驶一周。
自己用暴力破解 结果时间复杂度过高
public class Solution
{
public int CanCompleteCircuit(int[] gas, int[] cost)
{
int[] res = new int[gas.Length];
int[] temp = new int[res.Length];
for (int i = 0; i < res.Length; i++)
{
res[i] = gas[i] - cost[i];
}
for (int i = 0; i < res.Length; i++)
{
int index = 0;
for (int j = i; j < res.Length; j++)
{
temp[index] = res[j];
index++;
}
for (int j = 0; j <i; j++)
{
temp[index] = res[j];
index++;
}
int sum = 0;
int t = 0;
while (t < res.Length)
{
sum = sum + temp[t];
if (sum < 0)
{
break;
}
else
{
t++;
}
}
if (sum >= 0)
{
return i;
}
}
return -1;
}
}
然后通过看官方的题解 自己重新写了一下
public class Solution
{
public int CanCompleteCircuit(int[] gas, int[] cost)
{
int sum = 0;
int Min=int.MaxValue;
int mid = -1;
for (int i = 0; i < gas.Length; i++)
{
sum = sum + gas[i] - cost[i];
if (Min > sum && sum < 0)
{
Min = sum;
mid = i;
}
}
if (sum < 0)
{
return -1;
}
return (mid+1)%gas.Length;}
}
可以这样理解,把每个加油站看成环上的一个节点,分别以abcdefg...来表示假设sum>=0但是找不到符合题目要求那样的一个点,那我从a出发,假设能够到达c但是到达不了d,那么abc这三个点cost之和就一定大于gas之和,那你再从d出发,也无法到达某一点,比如说t吧,那么d到s(t前一个节点)(含端点)这一个区间cost之和就也一定大于gas之和,以此类推,(为了便于说明,假设第一圈中最后一个出发点为λ)最后可能有两种情况,第一种情况可能恰好到不了a,那么正好一段一段的覆盖了整个区间,整个区间的每一小段cost都大于gas,那么和肯定大于gas,矛盾。第二种可能能够到达a但是无法到达a后面的某一个点,假设无法到达f吧,那么λ到e之间cost之和大于gas之和。这时我们利用一下官解中的结论(为了恰好用任意段小区间覆盖整个环),由于e在d和s之间嘛,前面我们说过了,从d出发无法到达t,那么从e出发也自然无法到达t,那么e与s之间cost之和一定也大于gas之和,这样,我们就成功找到了某些段小区间,这些小区间cost之和都大于gas之和,所以能推导出整个环cost和小于gas之和,推出矛盾,若sum>=0则必有解。
官方题解
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int n = gas.length;
int i = 0;
while (i < n) {
int sumOfGas = 0, sumOfCost = 0;
int cnt = 0;
while (cnt < n) {
int j = (i + cnt) % n;
sumOfGas += gas[j];
sumOfCost += cost[j];
if (sumOfCost > sumOfGas) {
break;
}
cnt++;
}
if (cnt == n) {
return i;
} else {
i = i + cnt + 1;
}
}
return -1;
}
}