【leetcode】134. Gas Station

aalanwyr 發表於 2022-01-22
LeetCode

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

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

Given two integer arrays gas and cost, return the starting gas station's index if you can travel around the circuit once in the clockwise direction, otherwise return -1. If there exists a solution, it is guaranteed to be unique

Example 1:

Input: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
Output: 3
Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.

Example 2:

Input: gas = [2,3,4], cost = [3,4,3]
Output: -1
Explanation:
You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 0. Your tank = 4 - 3 + 2 = 3
Travel to station 1. Your tank = 3 - 3 + 3 = 3
You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
Therefore, you can't travel around the circuit once no matter where you start.

Constraints:

  • gas.length == n
  • cost.length == n
  • 1 <= n <= 105
  • 0 <= gas[i], cost[i] <= 104

 這道題需要求一個起始的站點k,從而保證從k站點開始,能夠迴圈一圈的遍歷所有station。這裡有兩點很直接的point:

1、如果當前station的 cost>gas那麼鐵定不能將該站點作為起始站點。

2、如果所有站點都能遍歷一遍,那麼gas的累加和一定是大於等於cost的累加和。

 對於這道題我首先想到了一個簡單的方法,迴圈遍歷陣列,讓每一個站點k作為起始站點試一遍,然後判斷能否跑到下一個站點,如果全部遍歷一遍都可以則輸出k,否則選擇下一個站點k+1作為起始,重複操作。很明顯這樣有兩層迴圈,時間複雜度為o(n^2),直覺告訴我鐵定不能oc。。。。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        // 暴力發就是每個gas station 進行檢索一次
        int n=gas.size();
        int len=2*n-1;
        int index=0;
        int flag=1;
        while(index<n){
            int res=0;
            flag=1;
            for(int i=index;i<=len;++i){
                res=res-cost[i%n]+gas[i%n];
                if(res<0) {
                    flag=0;
                    break;
                }
            }
            if(flag) break;
            index++;
        }
        return flag==1? index:-1;
    }
};

【leetcode】134. Gas Station

   倒在最後一個超長的test了。

  那麼如何優化呢,o(n^2)的複雜度指定不行的。後面看了大佬的程式碼才恍然大悟。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        // 暴力發就是每個gas station 進行檢索一次
        int tot_gas=0,cur_gas=0,k=0;
        for(int i=0;i<gas.size();++i){
            tot_gas+=gas[i]-cost[i];
            cur_gas+=gas[i]-cost[i];
            if(cur_gas<0){
                cur_gas=0;
                k=i+1; //這行程式碼很關鍵
            }
        }
        return tot_gas>=0? k:-1;
        
    }
};

    這裡維護 tank 總的 tot_gas,以及當前 tankcur_gas,更新方式基本相同  tot_gas+=gas[i]-cost[i];,但注意一點,當 cur_gas<0 時表明汽車無法到達該station,同時也表明從上一個起點 k 到當前的  station i 之間的任何 station 都無法作為起點進行迴圈,下一個起點得是  k=i+1(very important)。

   為啥呢,假設從 起點 k=0 開始,當從  station i-1=》station icur_gas[i]<0 , 可以證明從  station  0~i, 這些結點都無法作為起點。我的思考如下:

1. cur_gas[i]<0 ,可以得到 對於當前  station i :cost[i]>gas[i],station i  無法作為起點。

2.假設能從 station 0station i-1,可以得到從 station 0作為起始的cur_gas[i-1] 一定是大於以station i-1 作為起始的cur_gas[i-1], 因為前面能到達的話,會累加很多之前正的cur_gas,這樣就可以證明,如果從station 0都無法到達station i=》從 station i-1 也無法到達 station i 所以無論以 0~i 哪個station 作為起點,計算得到的cur_gas[i] 都必將為為負值

3.則下一個起點必然是station i+1

4.最後判斷一下tot_gas, 如果能夠迴圈檢索,必然總的tot_gas為正值。

該程式碼直接複雜度直接為o(n),賊牛逼。