【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;      }  };