[LeetCode] 134. Gas Station

加油站。题意是给一个长度为N的环,用数组表示。环上的每一个点都有两个值,一个是当前加油站的油量,一个是开到下一个加油站的耗油量。请找到一个起点能够保证车开完一圈,返回起点的坐标;若找不到这个起点则返回-1。例子,

Example 1:

Input: 
gas  = [1,2,3,4,5]
cost = [3,4,5,1,2]

Output: 3

Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.

这是一个数学题。这个题涉及一个定理(此处不证明了),如果一个数组的总和非负,那么一定可以找到一个起始位置,从它开始绕数组一圈,累加和一直都是非负的。有了这个定理之后,可以对input做如下判断。

1. 从位置i开始直到绕完一圈,如果油箱没空,说明从i开始所有的累积都是正的(总的加油量大于耗油量);

2. 如果在位置j的时候油箱空了,说明从位置i开始是走不完全程的,此时可以从j + 1的位置重新开始计算。为什么不考虑从i + 1的位置开始重新计算是因为i处的油量是正的情况下已经走不完全程了,如果从i + 1开始,更走不完全程了。

时间O(n)

空间O(1)

 1 /**
 2  * @param {number[]} gas
 3  * @param {number[]} cost
 4  * @return {number}
 5  */
 6 var canCompleteCircuit = function (gas, cost) {
 7     // corner case
 8     if (gas.length === 0 || cost.length === 0) return -1;
 9 
10     // normal case
11     let total = 0;
12     let sum = 0;
13     let start = 0;
14     for (let i = 0; i < gas.length; i++) {
15         total += (gas[i] - cost[i]);
16         if (sum < 0) {
17             sum = gas[i] - cost[i];
18             start = i;
19         } else {
20             sum += gas[i] - cost[i];
21         }
22     }
23     return total < 0 ? -1 : start;
24 };

猜你喜欢

转载自www.cnblogs.com/aaronliu1991/p/12302111.html