Leetcode 134加油站

题目描述:

 

 

题解:

第一反应是用暴力去模拟,直接模拟需要O(n^2)的时间复杂度。实际上这题有规律可循

规律一:记res_gas为剩余的gas,res_cost为剩余需要消耗的油量,cur为gas[pos]-cost[pos],pos为当前到达加油站的位置。在模拟到一个节点的时候,res_gas < res_cost或者cur<0的时候,无法环驶一圈。

规律二:记以pos_s为起点,在pos的时候发现无法环驶一周,那么pos_s ->pos之间的点都不能作为起点。

简单讨论一下规律二,在pos的时候发现无法环驶一周无非两种情况:

  第一种情况cur<0,在pos的时候cur < 0,那么从pos_s+1到pos选择的起点在pos的时候cur都会小于0。由于[pos_s,pos]区间内的每个点cur都是大于等于0的,记gas_sum为出发点到pos gas的总和,cost_sum同理,

此时gas_sum < cost_sum.无论从pos_s+1到pos选择哪个节点作为出发点,每个点的gas都大于等于cost,所以gas_sum始终小于 cost_sum.

  第二种情况res_gas < res_cost,论证的方式和第一种情况类似。

规律二比较重要,有了这个规律只需要一次遍历就可以找到合适的起点。

 

 

AC代码:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int Len = gas.size();
        int tol_gas,tol_cost;
        int res,cur;
        tol_cost = tol_gas = res = cur = 0;
        int flag = 1;
        int pos;
        for(int i=0;i<Len;i++) 
        {
            tol_gas += gas[i];
            tol_cost += cost[i];
        }
        if(tol_gas < tol_cost) return -1;
        int gas_sum,cost_sum;
        gas_sum = cost_sum = 0;

        for(int i=0;i<Len;i++)
        {
            if(flag == 1)
            {
                pos = i;
                flag = 0;
               // continue;
            }
            gas_sum += gas[i];
            cost_sum += cost[i];

            int cur = gas_sum-cost_sum;
            int res = (tol_gas-gas_sum)-(tol_cost-cost_sum)+cur;
            
            if(res < 0 || cur < 0)
            {
             //   cout << i <<endl;
                gas_sum = 0;
                cost_sum = 0;
                flag = 1;
                continue;
            }
        }
        if(flag == 1) return -1;
        return pos;
    }
};

 

posted @ 2020-03-05 15:20  猪突猛进!!!  阅读(192)  评论(0编辑  收藏  举报