Problem
Notes
思路一:暴力O(n^2)
思路二是看别人的题解学到的:
有这样一个数学定理:
如果一个数组的总和非负,那么一定可以找到一个起始位置,从他开始绕数组一圈,累加和一直都是非负的
那么,这样一来,根据上述定理,只要判断整个数组的和就能知道有没有可行解。
其次要考虑怎么得到起始位置,考虑若从i~j位置的汽油汽油余量为负(j>i),那么在思路一中我们需要回到i+1位置开始计算。
其实推敲一下就会发现,若以i为起点,到达j余量才<0(j>i),因为i这个点的余量一定是>=0的(否则根本走不动),那么如果从i+1~j肯定是无法到达的,因为整个序列和少了一个非负数。
那么我们就可以直接从j+1位置作为起点,不用回溯到i+1继续计算。这样就把复杂度降到了O(n)。
Codes
//思路一
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int len=gas.size();
int ans=-1;
for(int start=0;start<len;++start)
{
int g=0;
bool b=false;
for(int i=start;i<len;++i)
{
g=g+gas[i]-cost[i];
if(g<0)
{
b=true;
break;
}
}
if(b) continue;
for(int i=0;i<start;++i)
{
g=g+gas[i]-cost[i];
if(g<0)
{
b=true;
break;
}
}
if(!b)
{
ans=start;
break;
}
}
return ans;
}
};
//思路二
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int len=gas.size();
//start把整个数组分为两部分,前部分为first,后部分为second
int start=0,first=0,second=0;
for(int i=0;i<len;++i)
{
second=second+gas[i]-cost[i];
if(second<0)
{
first+=second;
second=0;
start=i+1;
}
}
return first+second>=0?start:-1;
}
};