【leetcode刷題】T174-加油站
- 2019 年 10 月 4 日
- 筆記
【題目】
在一條環路上有 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 升汽油。 因此,無論怎樣,你都不可能繞環路行駛一周。
【思路】
如果加油站總的汽油數小於cost總的汽油數,那麼必定無解,反之必定有解。
如果有解,怎麼來找到起始點呢。
起始點肯定不是 gas[i] – cost[i]<0 的汽油站
當然,選定起始點後,行進途中,如果cost汽油大於添加汽油,那麼沿途的所有加油站都不可以作為起始點。
使用數組num,num[i] = gas[i] – cost[i]。
使用start保存起始點(起始點必須滿足num[i] >= 0),「前進」求得子數組和,只要和小於0,則start置為-1,並且等待下一次nums[i] >= 0。
【程式碼】
python版本
class Solution(object): def canCompleteCircuit(self, gas, cost): """ :type gas: List[int] :type cost: List[int] :rtype: int """ # 總的gas還沒有cost多,則不可能 if sum(gas) < sum(cost): return -1 num = [gas[i] - cost[i] for i in range(len(gas))] dp = [-1] * len(gas) sum0 = 0 start = -1 # 子數組和不為負 for i, n in enumerate(num): if start != -1: sum0 += n if sum0 < 0: start = -1 elif n >= 0: start = i sum0 = n return start
C++版本
class Solution { public: int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { vector<int> num(gas.size(), 0); int sum0 = 0; for(int i=0; i<num.size(); i++){ num[i] = gas[i] - cost[i]; sum0 += num[i]; } // gas還沒有cost多,肯定不可能 if(sum0 < 0) return -1; // sum0用來存子數組和 sum0 = 0; int start = -1; for(int i=0; i<num.size(); i++){ if(start != -1){ sum0 += num[i]; if(sum0 < 0){ start = -1; } }else{ if(num[i] >= 0){ start = i; sum0 = num[i]; } } } return start; } };