1. 程式人生 > >[leetcode] Gas Station

[leetcode] Gas Station

題目描述:

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

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from stationi 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.最直觀的解法

  分別選取0~N-1站點作為起始點,計算從該起始點出發能否再回到該起始點,考慮到從p點到q點需要滿足方程組:

    gas[p]>=cost[p]

    gas[p]+gas[p+1]>=cost[p]+cost[p+1]

    ....

    gas[p]+gas[p+1]+...+gas[q-1]>=cost[p]+cost[p+1]+...+cost[q-1]

 故可以用兩個變數totalgas和totalcost依次累加gas[p]和cost[p] ,  若直到p==q時totalgas仍然不小於totalcost, 則說明從點p出發可以回到p點。  否則不行

 這種方法最直觀,但複雜度最高,為平方階。程式碼如下:

class Solution {
public:
    
    bool testStartPoint(vector<int> &gas,vector<int> &cost,int startPos,int N)
    {
        int totalgas=0,totalcost=0,curPos;
        for(curPos=startPos;curPos<N;++curPos)
        {
            totalgas+=gas[curPos];
            totalcost+=cost[curPos];
            if(totalgas<totalcost)
                return false;
        }
        for(curPos=0;curPos<startPos;++curPos)
        {
            totalgas+=gas[curPos];
            totalcost+=cost[curPos];
            if(totalgas<totalcost)
                return false;
        }
        return true;
    }


    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        int N=gas.size();
        for(int i=0;i<N;++i)
        {
            if(testStartPoint(gas,cost,i,N))
                return i;
        }
        return -1;
    }
};

2.思路變換一

假設要使車走的更遠些,則肯定會選擇這樣的站點為起點:從該站點出發,先遇到的都是那些加油大於耗油的站,以使得車攢夠足夠的油來度過那些耗油多過加油的站點。如果從該點出發仍不能走一圈,則應返回-1.

對於站點i,我們把gas[i]-cost[i]作為一個整體來考慮,令diff[i]=gas[i]-cost[i],表示從站點i出發到i+1站點後剩餘的油量。則要想使車輛走的更遠些,應選擇可以使diff的累加值達到峰值的點作為起始點。

從而問題轉化為求diff陣列上和最大的連續子陣列。也即求迴圈陣列的和最大連續子陣列。由動態規劃求可達到線性複雜度。由於是迴圈陣列,可求出和最大連續陣列MAX,以及和最小連續陣列MIN,  然後取MAX和total-MIN中的較大者即為和最大連續子陣列,其中total為陣列所有數的和。  由於我們要找的是連續陣列的起始點,即為MAX的起始點或者MIN的終止點的下一個點。

程式碼如下,O(n)

class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        if(gas.size()!=cost.size()) return -1;
        int N=gas.size();
        if(N==0) return -1;
        int MAX,MIN,max,min;
        int total=0;
        int stmax,stMax,endMin;
        MAX=MIN=max=min=gas[0]-cost[0];
        stmax=stMax=endMin=0;
        int diff;
        for(int i=0;i<N;++i)
        {
            diff=gas[i]-cost[i];
            total+=diff;
            
            if(max<0)
            {
                max=diff;
                stmax=i;
            }
            else
            {
                max+=diff;
            }
            if(max>MAX)
            {
                MAX=max;
                stMax=stmax;
            }
            if(min>0)
            {
                min=diff;
            }
            else
            {
                min+=diff;
            }
            if(min<MIN)
            {
                MIN=min;
                endMin=i;
            }
        }
        
        return total<0?-1:(MAX>(total-MIN)?stMax:(endMin+1)%N);
    }
};


3.思路變換二

解法一是依次從每個站點出發測試能否回到原點,這其中有很多次測試是不必要的。

假設從站點i出發,到站點k-1時油箱未空,但到k之前油箱空了,即diff[i]+diff[i+1]+...+diff[k]<0 ,且在從i到k之前的所有diff的累加均不小於0,也即diff[i]>=0,diff[i]+diff[i+1]>=0...

所以若從站點i+1出發,由於diff[i]>=0 ,所以,diff[i+1]+diff[i+2]+...+diff[k]<0,從而車也不能到達k點,i+2,i+3。。。等節點同理。  所以下一次應從k+1節點開始出發測試。

因此將複雜度從O(n^2)降到了O(2n),之所以是2n,是因為從k+1出發的測試需要繞一圈到k才能判斷是否滿足。

但是,真的需要這樣麼?

我們可以模擬一下過程:

a. 假設從0出發,開出p點後沒油了。則sum1=diff[0]+diff[1]+...+diff[p]<0

b.接著從p+1出發,開出q點後沒油了。則sum2=diff[p+1]+diff[p+2]+....diff[q]<0

c.從q+1出發,假設開到未迴圈的最後一站還有油,則sum3=diff[q+1]+diff[q+2]+...diff[size-1]>0

要想知道能否開回到q點,就是在sum3的基礎上依次加上diff[0]到diff[q],看過程中是否會出現小於0 的情況。而由先前的討論我們已經知道了從diff[0]到diff[p-1]的這一段的累加始終為非負。所有隻需計算sum3+sum1,若不小於0則可以開到p點,同理從p到q點也是此思路,最後得出結論即 若sum1+sum2+sum3>=0 則可以走一圈。 而sum1+sum2+sum3即為整個diff陣列的累加和。

此時複雜度為O(n),程式碼如下:

class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        if(gas.size()!=cost.size()) return -1;
        int N=gas.size();
        if(N==0) return -1;
        int sum=0,total=0,start=0;
        for(int i=0;i<N;++i)
        {
            total+=(gas[i]-cost[i]);
            
            if(sum<0)
            {
                sum=gas[i]-cost[i];
                start=i;
            }
            else
                sum+=(gas[i]-cost[i]);
        }
        return total<0?-1:start;
    }
};

相關推薦

[leetcode] Gas Station

題目描述: There are N gas stations along a circular route, where the amount of gas at stationi is gas[i]. You have a car with an unlimited g

leetcode 刷題之路 68 Gas Station

rom 說明 之路 bsp margin tom otto mono lee There are N gas stations along a circular route, where the amount of gas at station i is gas[i]

[leetcode]134. Gas Station加油站

CA ise 如何 ring exists log public 積累 www There are N gas stations along a circular route, where the amount of gas at station i is gas[

LeetCode:134. Gas Station(Week 7)

134. 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

LeetCode 134 Gas Station

LeetCode 134 Gas Station 水題,暴力一下就ok class Solution { public: int tag[100005]; int sum[100005]; int canCompleteCircuit(vector<int>&

[Leetcode 134]汽車加油站 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 unl

leetcode 134. Gas Station

leetcode 134. 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 ca

python leetcode 134. Gas Station 135. Candy

考察是將題目轉化為程式碼的能力 134. Gas Station class Solution(object): def canCompleteCircuit(self, gas, cost): """ :type gas: List[int]

LeetCode】#134加油站(Gas Station)

【LeetCode】#134加油站(Gas Station) 題目描述 在一條環路上有 N 個加油站,其中第 i 個加油站有汽油 gas[i] 升。 你有一輛油箱容量無限的的汽車,從第 i 個加油站開往第 i+1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發,開

[LeetCode] Minimize Max Distance to Gas Station 最小化去加油站的最大距離

On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., stations[N-1], where N = stations.length. Now, we add 

Leetcode 774. Minimize Max Distance to Gas Station

Problem: On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., stations[N-1], where N = stations.length. Now, we

LeetCode 134. Gas Station(java)

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 i

LeetCode--134. Gas Station

題目連結:https://leetcode.com/problems/gas-station/ 這個題目題意很繞,但是十分簡單,最樸素的思路就是暴力檢查一遍,不過有個小技巧——整除餘數的性質:就是檢查到陣列末端的陣列後,索引i越界,計算陣列長度的餘數就能回到起始端,這裡還要注意索引0前的一個元素

Leetcode Week7 Gas Station

Question 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

LeetCode-面試演算法經典-Java實現】【134-Gas Station(加油站問題)】

原題   There are N gas stations along a circular route, where the amount of gas at station i i

LeetCode-134-Gas Station

xpl vector put rect nco pla else can limited 算法描述: here are N gas stations along a circular route, where the amount of gas at station i i

Leetcode 134 Gas Station(環形最大連續和)

解題思路:目標可以轉換為從哪個位置開始,可以獲得連續最長的淨Gas收入。class Solution { public: int canCompleteCircuit(vector<int&

134. Gas Station

下一個 tar travel emp pan col ons -c amount There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

PAT 1072 Gas Station (30)

esp 狀態 solution sam 不知道 specific 解決方案 sep ans A gas station has to be built at such a location that the minimum distance between the stat

PAT-ADVANCED1072——Gas Station

我的PAT-ADVANCED程式碼倉:https://github.com/617076674/PAT-ADVANCED 原題連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805396953219072