1. 程式人生 > >leetcode134_加油站

leetcode134_加油站

在一條環路上有 N 個加油站,其中第 i 個加油站有汽油 gas[i] 升。

你有一輛油箱容量無限的的汽車,從第 i 個加油站開往第 i+1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發,開始時油箱為空。

如果你可以繞環路行駛一週,則返回出發時加油站的編號,否則返回 -1。

說明: 

如果題目有解,該答案即為唯一答案。
輸入陣列均為非空陣列,且長度相同。
輸入陣列中的元素均為非負數。
示例 1:

輸入: 
gas  = [1,2,3,4,5]
cost = [3,4,5,1,2]

輸出: 3

解釋:
從 3 號加油站(索引為 3 處)出發,可獲得 4 升汽油。此時油箱有 = 0 + 4 = 4 升汽油
開往 4 號加油站,此時油箱有 4 - 1 + 5 = 8 升汽油
開往 0 號加油站,此時油箱有 8 - 2 + 1 = 7 升汽油
開往 1 號加油站,此時油箱有 7 - 3 + 2 = 6 升汽油
開往 2 號加油站,此時油箱有 6 - 4 + 3 = 5 升汽油
開往 3 號加油站,你需要消耗 5 升汽油,正好足夠你返回到 3 號加油站。
因此,3 可為起始索引。
示例 2:

輸入: 
gas  = [2,3,4]
cost = [3,4,3]

輸出: -1

解釋:
你不能從 0 號或 1 號加油站出發,因為沒有足夠的汽油可以讓你行駛到下一個加油站。
我們從 2 號加油站出發,可以獲得 4 升汽油。 此時油箱有 = 0 + 4 = 4 升汽油
開往 0 號加油站,此時油箱有 4 - 3 + 2 = 3 升汽油
開往 1 號加油站,此時油箱有 3 - 3 + 3 = 3 升汽油
你無法返回 2 號加油站,因為返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,無論怎樣,你都不可能繞環路行駛一週。

 

思路:

如果一個數組的總和非負,那麼一定可以找到一個起始位置,從他開始繞陣列一圈,累加和一直保持非負。

  因此只要計算出一圈後加油與用油最後的總和是否大於0即可判斷是否有解。gas[i] >= cost[i]即可走向下一站

  對於找到起始位置,可以遍歷陣列,假設從i開始前進,到達j的時候沒油了,那麼我們下一步不應該從i+1開始遍歷,而是應該直接從j+1開始遍歷。

  因為如果i到j的剩餘油量小於0,而i顯然油量大於0,那麼從i+1到j就必定更小,同理,i+2,i+3也不用考慮,所以就應該直接從j+1開始繼續遍歷,並儲存之前欠缺的油量總和。
 

 

貼程式碼:

一旦從點i開始,經過若干站後不能到達點j(j為i開始第一個不能到達的點)那麼從點i到點j之間的任意一點開始都不可能到達點j
     所以  從i開始前進,到達j的時候沒油了,那麼我們下一步不應該從i+1開始遍歷,而是應該直接從j+1開始遍歷。

 public static int canCompleteCircuit(int[] gas, int[] cost) {
			int sum=0;      //油箱裡的油  可能為負數  
			int total=0;
			int start=0;
			for (int i = 0; i < gas.length; i++) {
				sum+=gas[i]-cost[i];      //到達下一個位置剩下的油  可能為負數
				if (sum<0) {  //如果為負數  表示累計和  不能到達i位置  則更不能到達i+1位置  所以起始位置應從下一個開始
					start=i+1;				
					total+=sum;      //total為到達i時總共要付出的油
					sum=0;             //從下一位置開始  所以sum置為0
				}
			}
		    total=total+sum;        //total為負數 要付出的   即是最終累計剩下的sum減去要付出的總和total
		    return total<0?-1:start;        
	    }