To solve this problem, some observations has to be made first.
Let's first see the relatively easy observations.
- To maximize the probability so we can complete the circuit and at each gas station, we'll add all the available gas to th E tank.
- If sum_{i = 1, 2, ..., k}gas[i] < Sum_{i = 1, 2, ..., k}cost[i], then we cannot reach K if we start f Rom i.
Make sure convince yourself of these and observations. They would serve as the foundation for the following trickier observations.
- Starting from I, if the first unreachable position are K, then we cannot reach position K if we Start from any position between I and K.
Let's do a quick proof. We use the proof by contradiction. Suppose we can reachkIf we start from the positionJWhich is betweenIandk. Now we can reachkFromJ. Moreover, we can reachJFromI(Sincekis the first unreachable position starting fromI). Putting these together, we'll first reachJFromI, and then reachkFromJ. This contradicts the assumption thatkIs isn't reachable fromI.
With this observation, each time we find the first point and the we cannot reach from the current starting position. We know that we don't need to check all the points between them and simply skip to the next point of the the first unreachabl E point.
Now comes the last observation, which are the key to give a O (n) solution.
- If the sum of gas isn't less than than the sum of cost, there must be a solution.
Well, the proof of this observation are not as easy as the above one. If There is only a gas stations, this observation is easy. When there is more than-stations, you could need to merge some of them to a single one and reduce the effective number of gas stations. You mar refer to this link for a proof.
Using These-observations, the idea to solve this problem is as follows.
Maintain a variableTankFor the net gas in the tank and a variable TotalTo accumulate the net difference between the sum of Gasand the sum of Cost. Then we initialize a variableStartTo IS0For the final starting position. Each time we find a unreachable point, we updateStartTo is the point after the current unreachable point. After we traverse all the points, we'll have the final net difference between the sum of Gasand the sum of Cost. If it isn't less than0, we know there must is a solution (according to the last observation) and returnStart. Otherwise, return-1.
The code is as follows.
1 classSolution {2 Public:3 intCancompletecircuit (vector<int>& Gas, vector<int>&Cost ) {4 intStart =0, total =0, tank =0;5 for(inti =0; I < (int) Gas.size (); i++) {6Tank + = Gas[i]-Cost[i];7 if(Tank <0) {8Start = i +1;9Total + =tank;TenTank =0; One } A } - returnTotal + Tank >=0? Start:-1; - } the};
Well, let's do more and the last observation. In fact, if the sum of than, the sum of cost, there exists a position with the minimum NE T gas (sum_{i=0, 1, ..., k}gas[i]-sum_{i = 0, 1, ..., k}cost[i] is minimized) and the starting point is simply The point after it.
Using This idea, we'll have a more succinct code.
1 classSolution {2 Public:3 intCancompletecircuit (vector<int>& Gas, vector<int>&Cost ) {4 intNET =0, start =0, min_net =0;5 for(inti =0; I < (int) Gas.size (); i++) {6NET + = Gas[i]-Cost[i];7 if(NET <min_net) {8Start = i +1;9Min_net =net;Ten } One } A returnNET >=0? Start:-1; - } -};
One final note, all of the above solutions is from this link in the Leetcode dicussion forum. Thank you to the nice sharer. Refer to it for more details.
[Leetcode] Gas station