方法一:直接暴力方法
解题思路:
当 gas[i] >= cost[i] 时,这个加油站才可能是个出发点,遍历gas容器(数组),当出现 gas[i] >= cost[i] 时,看看以这个加油站为出发点,是否满足条件,即执行函数whetherEnough,如果满足,就得到结果了,返回索引 i 即可,否则,继续寻找下一个可能的出发点。
在whetherEnough函数中,因为是个环形线路,所以先访问 i 后面的加油站,再访问 i 前面的加油站。中途一旦遇到剩余的油量为负,则这条路不通,返回false。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
//遍历gas和cost,gas[i] >= cost[i]的时候,i才可能为出发的加油站编号
for(int i = 0; i < gas.size(); i++){
if(gas[i] >= cost[i]){ //可能是个出发点
if(whetherEnough(i, gas, cost)) return i;
}
}
return -1;
}
bool whetherEnough(int n, const vector<int> gas, const vector<int> cost){
//输入的i为出发站,
int i = n;
int save = 0;
while(i < gas.size()){
save += (gas[i] - cost[i]);
if(save < 0) return false;
else i++;
}
for(int j = 0; j < i; j++){
save += (gas[j] - cost[j]);
if(save < 0) return false;
}
return true;
}
};
方法二:有点技巧
解题思路:
遍历gas容器(数组),分别要做两件事情:一是用变量save来记录剩余油量;二是要找到油量从负变为正的加油站点,即要用start来记录出发加油站点。
我们思考一下为什么会让出发站点放在中间,就是因为前面的数,gas加起来要小于cost,消耗多于供给。而起点后面的加油站,总供给要多于消耗,这样才能走完整个环路。
如果前面的加油站中,debt累加起来是正值,说明之前记录的start位置没有问题,如果出现了debt为负值,说明前面的加油站供给不足,要更新start变量。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int start = 0;
int save = 0;
int debt = 0;
for(int i = 0; i < gas.size(); i++){
save += gas[i] - cost[i];
debt += gas[i] - cost[i];
if(debt < 0){
start = i + 1;
debt = 0;
}
}
if(save >= 0) return start;
else return -1;
}
};