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

來源:互聯網
上載者:User

標籤:加油站   演算法   面試   java   

【134-Gas Station(加油站問題】 【LeetCode-面試演算法經典-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 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個加油站,其中氣體在車站i是量是gas[i]。你有車有無限容量的氣罐,從加油站i到下一個加油站網站i+1,要消耗cost[i]的氣體。你開始旅程時,氣罐是空的。回到起始加油站的指數,選擇一個起點開始旅遊,如果你能在周圍環形旅行一次,就返回開始的加油站索引,否則返回-1。
  注意: 答案保證是唯一的。

解題思路

  假設從網站 i 出發,到達網站 k 之前,依然能保證油箱裡油沒見底兒,從k 出發後,見底兒了。那麼就說明 diff[i] + diff[i+1] + … + diff[k] < 0,而除掉diff[k]以外,從diff[i]開始的累加都是 >= 0的。也就是說diff[i] 也是 >= 0的,這個時候我們還有必要從網站 i + 1嘗試嗎?仔細一想就知道:車要是從網站 i+1出發,到達網站k後,甚至還沒到網站k,油箱就見底兒了,因為少加了網站 i 的油。。。
  因此,當我們發現到達k 網站郵箱見底兒後,i 到 k 這些網站都不用作為出發點來實驗了,肯定不滿足條件,只需要從k+1網站嘗試即可!因此解法時間複雜度從O(n2)降到了 O(2n)。之所以是O(2n),是因為將k+1站作為始發站,車得繞圈開回k,來驗證k+1是否滿足。
  等等,真的需要這樣嗎?
  我們類比一下過程:
  a. 最開始,網站0是始發站,假設車開出網站p後,油箱空了,假設sum1 = diff[0] +diff[1] + … + diff[p],可知sum1 < 0;
  b. 根據上面的論述,我們將p+1作為始發站,開出q站後,油箱又空了, 設sum2 = diff[p+1] +diff[p+2] + … + diff[q],可知sum2 < 0。
  c. 將q+1作為始發站,假設一直開到了未迴圈的最末站,油箱沒見底兒,設sum3 = diff[q+1] +diff[q+2] + … + diff[size-1],可知sum3 >= 0。
  要想知道車能否開回 q 站,其實就是在sum3 的基礎上,依次加上 diff[0] 到 diff[q],看看sum3在這個過程中是否會小於0。但是我們之前已經知道 diff[0] 到 diff[p-1] 這段路,油箱能一直保持非負,因此我們只要算算sum3 + sum1是否 <0,就知道能不能開到 p+1站了。
  如果能從p+1站開出,只要算算sum3 + sum1 + sum2 是否 < 0,就知都能不能開回q站了。
  因為 sum1, sum2 都 < 0,因此如果 sum3 + sum1 + sum2 >=0 那麼sum3 + sum1 必然 >= 0,也就是說,只要sum3 + sum1 + sum2 >=0,車必然能開回q站。而sum3 + sum1 + sum2 其實就是 diff數組的總和 Total,遍曆完所有元素已經算出來了。
  因此 Total 能否 >= 0,就是是否存在這樣的網站的 充分必要條件。
  這樣時間複雜度進一步從O(2n)降到了 O(n)。

代碼實現

演算法實作類別

public class Solution {    public int canCompleteCircuit(int[] gas, int[] cost) {        // 參數檢驗        if (gas == null || cost == null || gas.length == 0 || gas.length != cost.length) {            return -1;        }        // 記錄訪問的起始點        int start = 0;        // 加的氣和消耗的氣的總差值        int total = 0;        // 從start位置開始,加的氣和消耗的氣的總差值        int sum = 0;        for (int i = 0; i < gas.length; 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 ? start : -1;    }    // 下面的方法會逾時O(N^2)時間複雜度    public int canCompleteCircuit2(int[] gas, int[] cost) {        // 參數檢驗        if (gas == null || cost == null || gas.length == 0 || gas.length != cost.length) {            return -1;        }        // 剩下的氣體,開始時為0        int leftGas = 0;        // 開始出發的網站        int start = 0;        // 結束的網站        int end = 1;        // 未走一周        while (start < gas.length) {            // 到達下一個站後的氣體簡便量            leftGas = gas[start] - cost[start];            // 可以走到下一個站            if (leftGas > 0) {                // 記錄下一個站                end = (start + 1) % gas.length;                // 如果一直可以到下一個站就持續進行操作                while (start != end && (leftGas += (gas[end] - cost[end])) >= 0) {                    end = (end + 1) % gas.length;                }                // 說明已經遍曆了一周                if (start == end) {                    return start;                }            }            start++;        }        return -1;    }}
評測結果

  點擊圖片,滑鼠不釋放,拖動一段位置,釋放後在新的視窗中查看完整圖片。

特別說明 歡迎轉載,轉載請註明出處【http://blog.csdn.net/derrantcm/article/details/47678215】

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.