有乙個環形軌道,上有若干加油站,一輛小車(初始時油箱為空,油箱容量無線)從某個加油站出發繞一圈,路上需要耗油,已知加油站的總油量和路上需要消耗地油量一樣多,問是否可以找到從乙個加油站出發,小車可以正常繞一圈?
其實上面的題與下面的題目類似:
有乙個迴圈陣列,,問找出乙個數,使得從該數出發,往右的所有子陣列,比如 , , , , , , 每個子陣列的和,都要 >= 0,即不為負。顯然以2開始,是不行的,因為 的和就是-1,已經不滿足條件了。
構造如下乙個雙向鍊錶,鍊錶節點中第乙個元素指示為index,第二個元素為對應的值:
<-> <-> <-> <-> <-> <->
順序掃瞄,從頭開始。找出第乙個節點,其值小於0,。
找出的節點為 ,那麼 * 我們要找的答案必須不是以該元素開始的,因為它已經是-3了*,那麼將 和前一項 ()整合,新的節點為 即 。整合後的節點的index值取整合前的前一項()的index值。
<-> <-> <-> <-> <->
現在發現 還是-1,那麼繼續往前整合:
<-> <-> <-> <->
ok,現在可以開始考慮 , 沒問題,繼續往下掃瞄。 遇到 節點時,又是-5,因此繼續往前整合:
<-> <-> <->
<-> <->
<-> // 將 與迴圈陣列的前一項()整合
此時剩下 ,繼續整合:
剩下index就是6,因此對應的那個值即 9,就是我們需要的答案。
每個節點最多被掃瞄一次和刪除一次。時間複雜度為 o(n),空間複雜度為 o(n)。
上述方案中,空間複雜度還是有點高。因此需要更好的方法。
其實在上述方案中,隱藏著另一幅視角:
倘若 arr[0..k]為 arr[0..0] ~ arr[0..n-1] 之間的和首次為負數,那麼 arr[0..k] 可以集成為乙個負數來看待。因此此時 arr[k] 必定是乙個必經大的負數,那麼該負數可以一直往前整合,直到把 arr[0]也整合進來。整合之後的值依然為負數。
ok,在上述情況下繼續討論,此時可以繼續直接從 arr[k+1]往下掃瞄。直到 arr[k+1 .. j] 為負數,此時這個區間的數可以整合成乙個負數。
直到從 arr[i .. n-1] 這段區間為正數,而且該正數可以恰好cover掉之前整合後的若干負數。那麼 i 就是我們所求的。 從 i 開始的n的長度遞增的子陣列,其和均為非負。
演算法思想:
sum
<- 0
foreach i in
0 .. n-1
sum<- sum + arr[i]
ifsum< 0
then
sum<- 0
else
if i == n-1
then
return i // 一定會有個i,是的該式子滿足 且此時 sum > 0
i <- i+1
時間複雜度為o(n),空間複雜度為o(1) N個加油站問題
問題 城市的環形路有n個加油站,第i個加油站的油量用gas i 來表示,你有如下的一輛車 它的油缸是無限量的,初始是空的 它從第i個加油站到第i 1個加油站消耗油量為cost i 現在你可以從任意加油站開始,路過加油站可以不斷的加油,問是否能夠走完環形路。如果可以返回開始加油站的編號,如果不可以返回...
074 加油站問題(優先佇列)
加油站問題,一輛車在每個加油站可以加一定數量的油,郵箱容量沒有上限,走乙個單位的路程消耗乙個單位的油量,問汽車是否能夠到達終點,如果可以,最少加幾次油?從這個角度思考問題較方便 當汽車經過某個加油站時,只把油裝在車上,並不加入油箱。等到油箱為空時再加油,與在加油站加油的效果一致。挑戰程式競賽 第二版...
問題 B 加油站(貪心 模擬)
problem link 時間限制 1 sec 記憶體限制 128 mb 提交 43 解決 9 提交 狀態 討論版 一輛汽車加滿油後可行駛 n公里。旅途中有若干加油站。設計乙個有效演算法,指出應在哪些加油站停靠加油,使沿途加油次數最少。請對於給定的 n和 k個加油站位置,計算最少加油次數。對於輸入資...