题目
分析一
暴力枚举每个点,看看能不能成为回路,如无则返回-1。
代码
1 class Solution { 2 public: 3 int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { 4 for(int i = 0;i < gas.size();i++){ 5 if(gas[i] < cost[i]) continue; 6 int s = gas[i] - cost[i]; 7 int j = (i+1) % gas.size(); 8 while(j != i){ 9 s = s + gas[j] - cost[j]; //剩余油量 10 if(s < 0) break; 11 j = (j + 1)%(gas.size()); 12 } 13 if(j == i) return j; 14 } 15 return -1; 16 } 17 };
分析二
1. 如果总油量小于总开销,那么无论从哪一点开始都不能走回路
2. 同时保存油箱从零开始最小的油量。如果最小的油量都大于等于零0,那么可以从零开始。
3.如果最小的油量小于零0,也就意味着从零开始到某一点最多缺 min多的油,然后从尾部开始查找可以填平 min值的位置,找到后该位置就为出发点。否则无法构成回路。
根据上面的图,意思从 i 开始往右每天都多存油,然后从0 到 i -1每天耗费油,最后正好填平意味着可以走回路。
代码
1 class Solution { 2 public: 3 int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { 4 int cur = 0; 5 int min = INT_MAX; //从起点出发,油箱里的最小值 6 for(int i = 0;i < gas.size();i++){ 7 int rest = gas[i] - cost[i]; 8 cur += rest; 9 if(cur < min) min = cur; 10 } 11 if(cur < 0) return -1; //油箱总量小于开销,一定跑不了一圈 12 if(min >= 0) return 0; 13 14 //油箱最小值为负数,从后往前看那个能把这个最小值填平 15 for(int i = gas.size()-1;i>=0;i--){ 16 int rest = gas[i] - cost[i]; 17 min += rest; 18 if(min >= 0) return i; 19 } 20 return -1; // 都填不平 21 } 22 };