zoukankan      html  css  js  c++  java
  • [LeetCode] Gas Station

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

    You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

    Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

    Note:
    The solution is guaranteed to be unique.

    意思就是:

    在一条环型线路上有N个加油站,每个加油站的油的数量是gas[i]。有一辆车,它有一个油箱可以装无限量的汽油,汽车从加油站i到下一个加油站i+1需要耗费cost[i]的汽油。

    问题是:该汽车汽油罐开始时是空的,如果该车能绕着环型线路走完,返回起始加油站的index;否则,返回-1。

    注意:如果存在方案,该方案必定是唯一的。

    解题思路:

    1,存在一种暴力求解法。即从每个加油站开始都计算一次。看能不能到达终点,但是时间肯定超时。

    2,较好的方法:任意选择一个加油站作为开始,一直往下走,如果到达某一站加的油减去耗费的油为负值,则选择截至的那个加油站的下一站作为起始站,继续计算 ;  直到计算完所有加油站为止。

    最后需要检测一下选择的起始站,能否跑完全程。

    有两个前提,令A[i] = gas[i]-cost[i]

    1 若A[0] + A[1] + ... + A[n-1] >= 0, 必存在 K,满足提议要求,A[k] >=0, A[K]+ A[K+1] >=0,....., A[K]+A[K+1]+ ... A[K-1] >=0.

    2  假设起点是 i, 走到 j 时, 发现剩下的油不够了. 暴力法 的做法是从 i+1 开始, 再走. 但是, A[i] >=0, 而A[i] + A[i+1] + ... A[j] < 0, 必有 A[i+1] + ... A[j] < 0,即从 从 i+1 ->j 之间的节点,肯定走不通。所以下一个起点应该是 j+1

    Code 如下

     1 class Solution {
     2 public:
     3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
     4         
     5         int n = gas.size();
     6         int total = 0;
     7 
     8         
     9         for(int i =0; i< n; i++)
    10         {
    11             total += (gas[i] - cost[i]);
    12         }
    13         
    14         if(total < 0)
    15             return -1;
    16             
    17         int sum = 0;
    18         int j = 0;
    19         
    20         for(int i =0; i< n; i++)
    21         {
    22             sum += (gas[i] - cost[i]);
    23             if(sum < 0)
    24             {
    25                 j=(i+1)%n;
    26                 sum = 0;
    27             }
    28         }        
    29         return j;
    30     }
    31 };

    再次精简:

     1 // 时间复杂度 O(n),空间复杂度 O(1)
     2 class Solution {
     3     public:
     4         int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
     5             int total = 0;
     6             int j = -1;
     7             for (int i = 0, sum = 0; i < gas.size(); ++i) {
     8                 sum += gas[i] - cost[i];
     9                 total += gas[i] - cost[i];
    10                 if (sum < 0) {
    11                     j = i;
    12                     sum = 0;
    13                 }
    14             }
    15             return total >= 0 ? j + 1 : -1;
    16         }
    17 };
  • 相关阅读:
    学习笔记:@RequestMapping
    学习笔记:serializable接口实现Java对象序列化
    学习笔记:JWT在spring中的时间
    学习笔记:JWT学习
    《OpenGL编程指南》学习进度备忘
    【练习7.4】使用直方图陆地移动距离EMD区分不同光线条件下的图片cvCalcEMD2
    【练习7.3】从直方图创建signature、计算两个直方图的EMD距离
    自动变量和开辟内存的生存期和作用域探讨
    【练习7.2】直方图归一化cvNormalizeHist、匹配cvCompareHist及各种匹配方法
    【练习7.1】cvCreateHist创建直方图、cvCalcHist计算直方图、cvQueryHistValue_1D访问直方图及右左法则
  • 原文地址:https://www.cnblogs.com/diegodu/p/3791221.html
Copyright © 2011-2022 走看看