题目描述:
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。
你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
- 如果题目有解,该答案即为唯一答案。
- 输入数组均为非空数组,且长度相同。
- 输入数组中的元素均为非负数。
一、我的O(n²)解法
遍历每个起点,从每个起点开始跑,若能够跑完全程,则返回起点,否则继续遍历,若遍历完成仍没有解,则返回 -1。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int current, flag; //current为在每个检查点的剩余油量,flag判断是否可以跑完
for (int i = 0; i < gas.size(); i++) //遍历起点
{
current = 0, flag = 1;
for (int j = 0; j < gas.size(); j++)
{
current += gas[(i+j)% gas.size()] - cost[(i+j)% gas.size()];
if (current < 0) //油不够了
{
flag = 0; //不能跑完
break; //若在一个检查点油量不够,则跳出
}
}
if (flag)
return i;
}
return -1;
}
};
二、题解O(n)解法
首先给出代码
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int judge = 0; //记录总加油量-总耗油量
int current = 0; //判断现有油量
int position = 0;
for (int i = 0; i < gas.size(); i++) //遍历每个起点
{
judge += gas[i] - cost[i];
current += gas[i] - cost[i];
if (current < 0) //若一个检查点不满足则之前所有检查点都是不满足的
{
position = i + 1; //开始测试下一个检查点
current = 0;
}
}
return judge >= 0 ? position : -1; //总加油-总耗油 推得两种情况①非负则有解②负则无解
}
};
核心思想:
1.是否有解是由 总加油-总耗油 决定的,小于0则无解,否则必定有解。(理解时可以将每个gas[i]-cost[i]看成一个整体)
2.解即出发位置是由 current 决定的,即现有油量,首先从位置0开始计算,当current小于0时则从0到此检查点都是不OK的,此时直接去检查后面一个位置,current清0.