题目
思路
自己的思路
因为要找到出发点,那么最初的思路就是:
- 设置一个变量,用于判断汽车是否能绕环一圈(因为加油总量和耗油总量如果为负数的话,那么说明是不能绕环一圈的)
- 然后再设置一个变量用于表示油箱油量剩余,如果油箱油量加上加油量大于耗油量,那么说明能继续开往下一个点,否则从该点出发是不能到达下一个点的,则此时将油箱油量设置为0(说明该点不能作为出发点)
- 我们再设置一个容器vector,将能开往下一个站点的点放进容器中,最后返回容器的第一个位置即可
相关代码如下:
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int nums = gas.size();
int rem = 0;//油箱油量
int all = 0;//用于判断是否能绕环一圈
vector<int> v;
for (int i = 0; i < nums; i++) {
if (rem + gas[i] >= cost[i]) {//如果能开往下一个站,则将该点压入容器中
v.push_back(i);
rem += gas[i] - cost[i];
}
else {//否则重新设置油箱油量
v.clear();
rem=0;
}
all += gas[i]-cost[i];
}
if (all >= 0)
return v.front();
return -1;
}
};
参考思路
我们知道,如果B点是A点第一个不能到达的点,那么A和B之间的点也都不能到达B点,那么如果我们在某一个站点,油箱量加上加油量小于耗油量,说明从该站点出发是不能到达下一个站点的,故该点不可能为出发点,所以我们就将出发点设置为下一个站点,同时将油箱油量设置为0,重复此步骤判断即可得出出发点
相关代码如下:
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int nums = gas.size();
int rem = 0;//邮箱剩余量
int all = 0;//总量
int res = 0;//保存起点站
for(int i=0;i<nums;i++){
rem += gas[i] - cost[i];
all += gas[i] - cost[i];
if (rem < 0) {//如果油箱存量小于0,说明不能到达k+1站,那么就将起点更新为k+1站
res = i + 1;
rem = 0;
}
}
return all < 0 ? -1 : res;
}
总结
该题属于贪心算法范畴,贪心算法每次都选取局部最优解,在该题中,我们每次都判断是否能开往下一个站点,如果不可以开往下一个站点,说明此时的局部最优解便是该站点不能作为出发点,最后由局部最优解得出整体最优解