难度中等
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i]
升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
- 如果题目有解,该答案即为唯一答案。
- 输入数组均为非空数组,且长度相同。
- 输入数组中的元素均为非负数。
思路一:暴力解法+剪枝
遍历数组,从数组中的每个位置开始尝试是否能够运行一周;剪枝-如果当前位置无法运行到下一个位置,之间到下一个位置开始。
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int len=gas.size();
for(int i=0;i<len;++i){
gas[i]-=cost[i];
}
int add=0,start=0,cur=0;
for(int i=0;i<len;++i){
if(gas[i]<0) continue;
for(add=0,start=0,cur=i;start<len;++start,++cur){
if(cur>=len) cur-=len;
add+=gas[cur];
if(add<0) break;
}
if(start>=len) return i;
}
return -1;
}
思路二:跳转位置
经数学分析,若是从位置 x 依次运动,遇到第一个无法到达的位置 y。则从 x 到 y 之间任何一个位置开始,都无法到达位置 y。
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int len=gas.size();
for(int i=0;i<len;++i){
gas[i]-=cost[i];
}
int add=0,start=0,cur=0;
for(int i=0;i<len;++i){
if(gas[i]<0) continue;
// 循环这个东西 找到当前不满足的位置,从当前不满足位置的下一个位置开始计算
for(add=0,start=0,cur=i;start<len;++start,++cur){
if(cur>=len) cur-=len;
add+=gas[cur];
if(add<0) break;
}
if(start>=len) return i;
i+=start-1;
}
return -1;
}