加油站問題(貪心演算法)
在一條環路上有 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 可為起始索引。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/gas-station
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
示例 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 升汽油。
因此,無論怎樣,你都不可能繞環路行駛一週。
一次遍歷
從頭到尾遍歷每個加油站,並檢查以該加油站為起點,最終能否行駛一週。
我們可以通過減小被檢查的加油站數目,來降低總的時間複雜度。
假設從加油站 x 出發,每經過一個加油站就加一次油(包括起始加油站),最後一個可以到達的加油站是 y(不妨設 x<y)。這就說明:
第一個式子表明無法到達加油站 y 的下一個加油站,第二個式子表明可以到達 y以及 y之前的所有加油站。
現在,考慮任意一個位於 x,y之間的加油站 z(包括 x和 y),我們現在考察從該加油站出發,能否到達加油站 y的下一個加油站,也就是要判斷之間的大小關係。
根據上面的式子,我們得到:
其中不等式的第二步、第三步分別利用了上面的第一個、第二個不等式。
從上面的推導中,能夠得出結論:從 x,y 之間的任何一個加油站出發,都無法到達加油站 y 的下一個加油站。
在發現了這一個性質後,演算法就很清楚了:我們首先檢查第 0個加油站,並試圖判斷能否環繞一週;如果不能,就從第一個無法到達的加油站開始繼續檢查。
複雜度分析
時間複雜度:O(N),其中 N 為陣列的長度。我們對陣列進行了單次遍歷。
空間複雜度:O(1)。
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int n=gas.length;
int i=0;
//從頭到尾遍歷每個加油站,並檢查以該加油站為起點,能否行駛一週
while(i<n){
int sumOfGas=0; //總共加的油
int sumOfCost=0; //總共消費的油
int count=0; //走過幾個站點
while(count<n){ //迴圈終止條件走過所有站點
int j=(i+count)%n; //加油站環形
sumOfGas+=gas[j];
sumOfCost+=cost[j];
if(sumOfCost>sumOfGas){ //若該站點油不夠終止迴圈
break;
}
count++; //站點滿足計數
}
if(count==n){ //環繞一週
return i;
}else{ //不行從下一個站點開始檢查
i=i+count+1;
}
}
return -1; //所有站點都不滿足
}
}
相關文章
- 貪心演算法——換酒問題演算法
- 貪心演算法篇——區間問題演算法
- 貪心-刪數問題
- 刪數問題(貪心)
- 活動選擇問題理解貪心演算法演算法
- 汽車加油問題 SDUT OJ 貪心演算法演算法
- 使用貪心演算法解決集合覆蓋問題演算法
- 區間問題的貪心方法
- [經典演算法]海盜分金問題sql求解(貪心演算法)演算法SQL
- 貪心演算法演算法
- 貪心例題
- 貪心演算法(貪婪演算法,greedy algorithm)演算法Go
- 貪心演算法Dijkstra演算法
- 探索貪心演算法:解決最佳化問題的高效策略演算法
- LeetCode解題記錄(貪心演算法)(二)LeetCode演算法
- LeetCode解題記錄(貪心演算法)(一)LeetCode演算法
- 學一下貪心演算法-學一下貪心演算法演算法
- 反悔貪心雜題
- Moving Tables(貪心演算法)演算法
- 9-貪心演算法演算法
- 揹包問題演算法全解析:動態規劃和貪心演算法詳解演算法動態規劃
- 常用演算法之貪心演算法演算法
- 「貪心」做題記錄
- 貪心 做題筆記筆記
- 演算法基礎–貪心策略演算法
- 馬踏棋盤演算法(騎士周遊問題)----遞迴與貪心優化演算法演算法遞迴優化
- 貪心(入門簡單題)
- 「演算法」貪心與隨機化演算法隨機
- 貪心
- python 實現 割繩子問題(劍指offer 14題) 動態規劃 或者貪心演算法Python動態規劃演算法
- 【LeetCode】貪心演算法–分發糖果(135)LeetCode演算法
- dfs與貪心演算法——洛谷5194演算法
- Find the Maximum - 題解【思維,貪心】
- 演算法---貪心演算法和動態規劃演算法動態規劃
- 資料結構與演算法——貪心演算法資料結構演算法
- 反悔貪心
- Supermarket(貪心)
- letcode加油站問題總結