2019-06-01 17:09:30數組
問題描述:ide
問題求解:ui
其實本題本質上是一個數學題。spa
【定理】code
對於一個循環數組,若是這個數組總體和 SUM >= 0,那麼必然能夠在數組中找到這麼一個元素:從這個數組元素出發,繞數組一圈,能保證累加和一直是出於非負狀態。blog
【證實】ci
從第一個數字開始進行累加和,中間必然會有一個累加和最低的點,咱們設爲x。最後的sum >= 0。數學
如今咱們從x出發向後累加,那麼必然處於非負狀態,而且到了最後一個站點還會有必定的盈餘,再從開始向最低點x進發也必然不會出現負數的狀況。string
【Leetcode Discuss】it
If sum of all
gas[i]-cost[i]
is greater than or equal to0
, then there is a start position you can travel the whole circle.
Leti
be the index such that the the partial sumgas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i]
is the smallest, then the start position should be
start=i+1
(start=0
ifi=n-1
). Consider any other partial sum, for example,gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i]+gas[i+1]-cost[i+1]
Since
gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i]
is the smallest, we must havegas[i+1]-cost[i+1]>=0
in order for
gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i]+gas[i+1]-cost[i+1]
to be greater.
The same reasoning gives thatgas[i+1]-cost[i+1]>=0 gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]>=0 ....... gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]+...+gas[n-1]-cost[n-1]>=0
What about for the partial sums that wraps around?
gas[0]-cost[0]+gas[1]-cost[1]+...+gas[j]-cost[j] + gas[i+1]-cost[i+1]+...+gas[n-1]-cost[n-1] >= gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i] + gas[i+1]-cost[i+1]+...+gas[n-1]-cost[n-1] >=0
The last inequality is due to the assumption that the entire sum of
gas[k]-cost[k]
is greater than or equal to 0.
So we have that all the partial sumsgas[i+1]-cost[i+1]>=0, gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]>=0, gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]+...+gas[n-1]-cost[n-1]>=0, ... gas[i+1]-cost[i+1]+...+gas[n-1]-cost[n-1] + gas[0]-cost[0]+gas[1]-cost[1]+...+gas[j]-cost[j]>=0, ...
Thus
i+1
is the position to start.
所以,對於本題來講,咱們能夠計算一下是否總的gas - cost >= 0?若是是,那麼必然存在一個解,在這個前提下,只須要遍歷一遍數組,若是碰到不能到達的狀況,那麼就從第一個不能到達的從新開始計算便可。
public int canCompleteCircuit(int[] gas, int[] cost) { int n = gas.length; int sum = 0; for (int i = 0; i < n; i++) sum += gas[i] - cost[i]; if (sum < 0) return -1; int start = 0; int tank = 0; for (int i = 0; i < n; i++) { tank += gas[i]; if (tank < cost[i]) { start = i + 1; tank = 0; } else { tank -= cost[i]; } } return start; }