[LeetCode OJ] 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.

代码一:

 1 class Solution {
 2 public:
 3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {  //时间复杂度为O(n)
 4         int total=0;
 5         unsigned i,j,start;
 6         for(i=0; i<gas.size(); )
 7         {
 8             start = i;
 9             int residual = gas[i]-cost[i];
10             total += gas[i]-cost[i];
11             
12             for(j =i+1; j<gas.size(); j++)
13             {
14                 if(residual<0)
15                 {
16                     i=j;
17                     break;
18                 }
19                 total += gas[j]-cost[j];
20                 residual += gas[j]-cost[j];
21             }
22             i=j;
23         }
24         return total>=0? start : -1;
25     }
26 };

代码二:

 1 class Solution {
 2 public:
 3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
 4         unsigned start = 0;
 5         int current_gas = 0;
 6         int total_gas = 0;
 7         for(unsigned i=0; i<gas.size(); i++)
 8         {
 9             current_gas += gas[i]-cost[i];
10             total_gas += gas[i]-cost[i];
11             if(current_gas<0)   //从第i站出发到第i+1站很耗油
12             {
13                 start = i+1;
14                 current_gas = 0;
15             }
16         }
17         return total_gas>=0 ? start : -1;
18     }
19 };

代码一和代码二的思想是一样的,只是形式不太一样,相比较而言,代码二可读性更好。

问题分析:

如果sum(gas)>=sum(cost),则一定存在一个合适的站点,使得从该站点出发汽车可以转一圈再返回到起始点,但是起始点的唯一性并不能保障。

比如gas=[4,5,6,7],cost=[1,2,3,4],则任一站点都可以作为起始点。

所以本题中给出Note:
The solution is guaranteed to be unique.

如果sum(gas)<sum(cost),则不存在这样的起始点,这一点很容易想到。

代码思想:

假设有n个站点:S1,S2,S3,...,Sn,当前油箱内油量为0,从S1开始,判断从S1站点能否开到S2站点,如果可以的话说明达到S2站点时汽车内油量>=0,

我们标记S1>0,表示从S1可以到达S2;否则,标记S1<0。     当Si>0时,继续判断Si+1是否大于0,当Si<0时,说明当前设置的起始点不成功,将新的起始点

设为Si+1,判断从Si+1->Si+2->...->Sn是否成功。    如果从Si+1能否到达Sn,并且sum(gas)>=sum(cost),那么Si+1就可以作为起始点。

   举个例子:                                            S1, S2, S3,    S4, S5, S6, S7,..., Si,  Si+1, Si+2,..., Sn             标记为绿色的表示在遍历过程中被设为起始点的站点

                                      current_gas     |>0    >0    <0 |   >0   >0   >0   >0,...,<0 |   >0      >0 ..., >0|

                                                            |       <0         |                    <0                   |            >0              |

                                                     sum(gas13)-sum(cost13)<0

原文地址:https://www.cnblogs.com/Marrybe/p/3780586.html