在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
#include <vector>
using namespace std;
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int total_gas = 0; // 总汽油量
int curr_gas = 0; // 当前油箱中的汽油量
int start = 0; // 出发加油站的索引
for (int i = 0; i < gas.size(); ++i) {
total_gas += gas[i] - cost[i]; // 计算总汽油量
curr_gas += gas[i] - cost[i]; // 更新当前油箱中的汽油量
// 如果当前油箱汽油不够用,无法到达下一个加油站
if (curr_gas < 0) {
start = i + 1; // 更新出发加油站的索引
curr_gas = 0; // 重新初始化当前油箱中的汽油量
}
}
// 如果总汽油量小于0,说明无法绕行一圈
if (total_gas < 0) {
return -1;
} else {
return start;
}
}
// 示例测试
int main() {
vector<int> gas = {1, 2, 3, 4, 5};
vector<int> cost = {3, 4, 5, 1, 2};
int result = canCompleteCircuit(gas, cost);
cout << result << endl; // 输出: 3
return 0;
}
解题思路:
初始化变量:total_gas 表示油箱中的总汽油量,curr_gas 表示当前油箱中的汽油量,start 表示出发加油站的索引,表示当前考虑的加油站索引。
遍历每个加油站:
计算从当前加油站出发,沿着环路行驶,是否能够回到当前加油站。具体做法是,从当前加油站开始模拟行驶,途中计算油箱剩余的汽油量,如果在任意时刻剩余汽油量小于0,则说明无法绕行一圈,将 start 索引更新为当前加油站的下一个加油站,并将 total_gas 和 curr_gas 重新初始化为 0。
返回 start。
时间复杂度分析:
此算法只需要一次遍历加油站数组,时间复杂度为 O(n),其中 n 为加油站的数量。
空间复杂度分析:
算法中只使用了常数级别的额外空间,因此空间复杂度为 O(1)。