问题描述
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油gas[i]
,并且从第_i_个加油站前往第_i_+1个加油站需要消耗汽油cost[i]
。
你有一辆油箱容量无限大的汽车,现在要从某一个加油站出发绕环路一周,一开始油箱为空。
求可环绕环路一周时出发的加油站的编号,若不存在环绕一周的方案,则返回-1
。
Solution 1
我们让 val[i] = gas[i] - cost[i] ,对于每一个 val[i] 我们去验证以它为起点能否环绕一周,这样做的时间复杂度自然是 O(n^2)
Java code:
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas == null || gas.length == 0 || cost == null || cost.length == 0)
return -1;
int len = gas.length;
int[] val = new int[len * 2];
for (int i = 0; i < len; ++i) {
val[i] = gas[i] - cost[i];
val[i + len] = val[i];
}
int sum = Integer.MIN_VALUE;
for (int i = 0; i < len; ++i) {
if (val[i] <= 0) continue;
sum = val[i];
for (int j = i + 1; j < i + len; ++j) {
sum += val[j];
if (sum < 0) break;
}
if (sum >= 0) return i;
}
return -1;
}
}
事实上,我们并不需要使用额外的数组来保存 gas[i] - cost[i] 的结果,可以在需要的时候再去计算,于是我们把空间复杂度降到了 O(1)
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas == null || gas.length == 0 || cost == null || cost.length == 0)
return -1;
int len = gas.length;
int sum = Integer.MIN_VALUE;
for (int i = 0; i < len; ++i) {
int vali = gas[i] - cost[i];
if (vali <= 0) continue;
sum = vali;
for (int j = i + 1; j < i + len; ++j) {
int valj = gas[j % len] - cost[j % len];
sum += valj;
if (sum < 0) break;
}
if (sum >= 0) return i;
}
return -1;
}
}
Solution 2
方案一的时间复杂度为 O(n^2) ,我们似乎不大满意,于是我们尝试去寻找效率更高的解法
事实上,只要总的汽油量大于总的消耗量,这个问题总是可以解的,我们只需遍历一次,时间复杂度为 O(n) , 具体代码如下
java code :
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
if (gas == null || gas.length == 0 || cost == null || cost.length == 0)
return -1;
int cur = 0;
int res = 0;
int val = 0;
for (int i = 0; i < gas.length; ++i) {
cur += gas[i] - cost[i];
val += gas[i] - cost[i];
if (cur < 0) {
res = i + 1;
cur = 0;
}
}
if (val >= 0) return res;
return -1;
}
}
Cpp code :
class Solution {
public:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
if (gas.empty() || cost.empty()) return -1;
int cur = 0;
int val = 0;
int res = 0;
for (int i = 0; i < gas.size(); ++i)
{
cur += gas[i] - cost[i];
val += gas[i] - cost[i];
if (cur < 0)
{
cur = 0;
res = i + 1;
}
}
if (val >= 0) return res;
return -1;
}
};
python code :
class Solution:
def canCompleteCircuit(self, gas, cost):
cur = 0; val = 0; res = 0
for i in xrange(len(gas)) :
cur += gas[i] - cost[i]
val += gas[i] - cost[i]
if cur < 0 :
res = i + 1
cur = 0
if val >= 0 :
return res
return -1;