题目链接:https://leetcode-cn.com/problems/gas-station/
题目描述
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
- 如果题目有解,该答案即为唯一答案。
- 输入数组均为非空数组,且长度相同。
- 输入数组中的元素均为非负数。
思路
(1)首先考虑什么时候题目会无解:当所有加油站的油量综合<总开销时,题目无解,所以我们用一个变量 total
来统计该值,如果total < 0
,返回-1
;否则题目必然有解。
(2)下面找出该起始点
首先我们初始化起始点为start=0
,用curr
表示到达下一个站时的油量,初始化为0,curr += gas[i] - cost[i]
,当遍历到某个加油站时,curr < 0,则表示以start
作为起始点无法到达该加油站。此时清空curr
,以下一个加油站作为起始点。
遍历完后返回start
。
为什么以start = i+1呢?
加入问题有解,假设从[i,j]区间,累积和total>=0;在 [i,k] curr<0,则在[k,j]必然有curr>0,所以以下一个节点作为新的起始点,同时注意把油箱清零。
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
代码
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int total = 0; // 所有加油站的油量-消耗累积和
int curr = 0; // 当前油量
int start = 0; // 初始化从0号加油站开始
for (int i = 0; i < gas.size(); ++i) {
curr += gas[i] - cost[i];
total += gas[i] - cost[i];
if(curr < 0){ // 无法到达下一个加油站
curr = 0; // 油量清空
start = i+1; // 将下一个加油站作为起点
}
}
return total < 0?-1:start;
}
};