134. 加油站 - 力扣(LeetCode)
先寻找起点,然后遍历:
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int n = gas.size();
for(int i = 0; i < n; ++i){//寻找起始点
if(gas[i] < cost[i]) continue;
int val = 0, j = i;
for(; j < i+n; ++j){
int idx = j % n;//首尾相连
val += gas[idx] - cost[idx];
if(val < 0) break;
}
if(val >= 0) return i;
}
return -1;
}
};
其实还有一个贪心算法的优化:加油站 - 加油站 - 力扣(LeetCode),推导很容易看懂。
total来记录 gas总数 - cost总数
,total < 0:返回-1
cur用来记录当前累计的gas[i] - cost[i]
,包含当前点的gas,并减去到达下一点的cost。
若cur < 0
,说明从起点start到当前点 i (包含 i ),中间的任何一点都不能作为出发点。因为在中间的任何一点上,都保证了cur >= 0
,把它当做出发点,并不能增加到达当前点 i的汽油量,也即仍然会出现cur < 0
的情况。所以需要更新出发点为当前点 i 的下一个。
直到遍历完成。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int total = 0, cur = 0, start = 0;
for(int i = 0; i < gas.size(); ++i){
total += gas[i] - cost[i];
cur += gas[i] - cost[i];
if(cur < 0){
start = i+1;
cur = 0;
}
}
return total<0 ? -1 : start;
}
};