Lintcode : 187 加油站
阿新 • • 發佈:2018-11-04
描述
在一條環路上有 N 個加油站,其中第 i 個加油站有汽油gas[i]
,並且從第_i_個加油站前往第_i_+1個加油站需要消耗汽油cost[i]
。
你有一輛油箱容量無限大的汽車,現在要從某一個加油站出發繞環路一週,一開始油箱為空。
求可環繞環路一週時出發的加油站的編號,若不存在環繞一週的方案,則返回-1
。
自己思路:採取的貪心策略就是看curGas,如果汽油可以一直累計>=0 那麼就是可行的,如果到第i步汽油累積量變負,說明i及i以前的加油站都不能出發
public int canCompleteCircuit(int[] gas, int[] cost) { // write your code here 要確認從該點出發後,會不會在後面的加油站卡住沒油了! int startIndex = -1; int curGas = 0; for (int i = 0; i < gas.length; i++) { int diff = gas[i] - cost[i]; if (diff > 0){ if (startIndex == -1) startIndex = i; curGas += diff; }else if (diff <= 0){ if (curGas + diff >= 0 && curGas > 0) curGas+= diff; else{ curGas = 0; startIndex = -1; } } } return startIndex; }
dalao思路:要考慮清楚問題的本質,開始出發的加油站一定是最後一個sum< 0 的後一個站,因為sum是加起來的總和,就算前面有一次使得sum > 0 ,但是之後sum 又小於0 說明前一次變正的加油站出發後仍然會卡住
public int canCompleteCircuit2(int[] gas, int[] cost) { if (gas == null || cost == null || gas.length == 0 || cost.length == 0) { return -1; } int sum = 0; int total = 0; int index = -1; for(int i = 0; i<gas.length; i++) { sum += gas[i] - cost[i]; total += gas[i] - cost[i]; if(sum < 0) { index = i; sum = 0; } } return total < 0 ? -1 : index + 1; // index should be updated here for cases ([5], [4]); // total < 0 is for case [2], [2] }
summary:
1、感覺情況比較複雜的時候,就耐心思考把所有情況列出來,這樣做題才有用
2、在這樣需要考慮未來的題中,不可能一下就出結果,採取貪心策略,如果當前滿足就把入口定在當前,當不滿足的時候就換入口並再次初始化相關變數,說的有點抽象,簡單的想就是需要一個變數記錄當前累積量,還需要一個變數記錄當前滿足條件的入口,根據累積量和題目條件在合適的時候換入口
3、有時候複雜的情況本質是一樣的,如果前面行得通後面行不通,那麼也相當於行不通,如果前面行不通,就更不用糾結前面過程中會不會有某個點行得通,只看後面就行
4、dalao的一個sum變數就取消了複雜的條件判斷因為問題的本質是該在那個加油站出發,使得以後的汽油也夠,那本質就是所有剩餘量加起來不小於0,sum<0 。累積性問題,注意累積量的本質性