leetcode 134 解析
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i]
升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
- 如果题目有解,该答案即为唯一答案。
- 输入数组均为非空数组,且长度相同。
- 输入数组中的元素均为非负数。
自己的答案,基本算是暴力解法了,双重循环,不过考虑实际情况大多数都break掉了,测试时间也还好,C++代码如下:
C++解法一:
1 class Solution { 2 public: 3 int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { 4 int re=-1,i=0,j=0; 5 int l=gas.size(); 6 while(re==-1&&i<l){ 7 gas.push_back(gas[i]);//下标每次后移前都把当前下标数目push_back 8 cost.push_back(cost[i]); 9 if(gas[i]>=cost[i]){//当前point满足出发条件进入子循环; 10 int oil=gas[i],m=0; 11 while(m<l-1){ 12 if(oil-cost[i+m]>=0){ 13 oil=oil-cost[i+m]+gas[i+m+1]; 14 m++; 15 }else{ 16 break; 17 } 18 } 19 if((m==l-1)&&(oil-cost[i+m]>=0)){ 20 re=i; 21 break; 22 } 23 } 24 i++; 25 } 26 return re; 27 } 28 };
最优解:
只遍历一遍,有三个特征量,total,sum,start
start用来记录起点,也就是最终的返回值;
total用来记录整个环的gas和cost,即验证能否满足走完一圈的最低条件;
sum用来记录start到当前点是否满足向前行驶的条件;
时间复杂度只有O(n);
但我总觉得这个程序实际上必须是满足total>0一定有解,这个解就是sum>0的第一个点的下标;至于为什么满足这个条件一定有解,等想明白了再更新;
C++解法二:
1 class Solution { 2 public: 3 int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { 4 int total=0,sum=0,start=0; 5 for(int i=0;i<gas.size();i++){ 6 total+=gas[i]-cost[i];//走完整个环的前提 7 sum+=gas[i]-cost[i];//走完起点到当前点的前提 8 if(sum<0){//当到达某一站点时油不够了,更换next为新起点 9 start=i+1; 10 sum=0; 11 } 12 13 } 14 return (total<0)? -1 : start; 15 } 16 };