题目描述
N个加油站呈环形分布,第i个加油站的油量为gas[i],你有一辆可以装无限油量的卡车,并且从加油站i到加油站i+1的途中需要消耗掉cost[i]的油量。油箱为空的条件下选择一个加油站起步并能够转一圈重新回到起点。
若不存在这样的加油站返回-1,否则返回该加油站的下标。
该题求线性的解法
方法一:最直观的解法为O(N^2)时间复杂度,挨个加油站尝试。
需要注意的是循环数组循环下标的转换。
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
for(int i=0;i<gas.length;i++)
{
int count=0;
for(int j=i;j<gas.length+i;j++)
{
//循环数组循环时下标的转换
count+=gas[j%gas.length]-cost[j%gas.length];
if(count<0)
break;
}
if(count>=0)
return i;
}
return -1;
}
}
方法二:在方法一的基础上提升了时间性能
public int canCompleteCircuit(int[] gas, int[] cost) {
for(int i=0;i<gas.length;i++)
{
gas[i]-=cost[i];
}
for(int i=0;i<gas.length;i++)
{
if(gas[i] < 0)
continue;
int count =0;
for(int j=i;j<i+gas.length;j++)
{
count+=gas[j%gas.length];
if(count < 0)
break;
}
if(count >= 0)
return i;
}
return -1;
}
方法三:
http://www.cnblogs.com/felixfang/p/3814463.html
这种解法其实依托于一个数学命题:
对于一个循环数组,如果这个数组整体和 SUM >= 0,那么必然可以在数组中找到这么一个元素:从这个数组元素出发,绕数组一圈,能保证累加和一直是处于非负状态。
public int canCompleteCircuit(int[] gas, int[] cost) {
int total=0;
int start=0;
int cursum=0;
for(int i=0;i<gas.length;i++)
{
total+=gas[i]-cost[i];
if(cursum<0)
{
cursum=gas[i]-cost[i];
start=i;
}
else
cursum+=gas[i]-cost[i];
}
return total<0?-1:start;
}