There are N gas stations along a circular route, where the amount of gas at station i is gas[i]
.
You have a car with an unlimited gas tank and it costs cost[i]
of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
Note:
The solution is guaranteed to be unique.
问题:在一个环形的路径上,有 n 个加油站。每个加油站 i 有汽油 gas[i] ,从 i 行驶到下一个加油站需要耗油 cost[i],汽车的油箱没有限制。找出一个加油站,从该加油站能走完整个环形路径。其中,本题目只有唯一一个解。
思路:
环形路径并且需要走完一整圈,则有:
1),若全部加油站的汽油 小于 路径总消耗油量,则不可能走完全程。
2),反之,若全部加油站的汽油 大于等于 路径总消耗油量,那么必然有至少存在一个站可以出发走完全程。
以上是我能想到的,至于如何环形路径中找到 2) 中的加油站,则没有什么思路。
在网上看到一个讲解,才明白,而解决方案的关键就是题目的限制条件“本题目只有唯一一个解”。
由于只有唯一解 i ,则以下性质:
性质1. 任何 j ( 0<= j < i) 都不可能到达 i 。
性质2. 任何 k (i <= i < n) ,i 都可以到达。
所以,从左往右扫,当遇到第一个i, 满足 sum[i,j] (i <= j < n) 均大于等于0,那么 i 便是题目的解。
若对每一个元素都检查 sum[i,j] ,那么耗时为 O(n*n) 。这里借助 性质1 优化查找。
假设 sum[i1, j] (i1<= j < t2) 都大于等于 0 ,当 j = t2 时,sum[i1, j] 小于 0 ,那么 i1 不是解,根据性质1,i1~ t2 都不是解。可以从 t2+1 开始继续扫。
1 int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { 2 3 vector<int> rem(gas.size()); 4 5 int totalrem = 0; 6 for ( int i = 0; i < gas.size(); i ++){ 7 rem[i] = gas[i] - cost[i]; 8 totalrem += rem[i]; 9 } 10 11 if (totalrem < 0) { 12 return -1; 13 } 14 15 int l = 0; 16 int sum = 0; 17 18 for (int i = 0 ; i < rem.size(); i++) { 19 sum += rem[i]; 20 if(sum < 0){ 21 sum = 0; 22 l = i + 1; 23 } 24 } 25 26 return l; 27 }
记录以下:最近做的几道 Greedy 类型的题目,自己基本没有很好的解题思路,即使看了几个讲解也没有找到他们的共通之处。看来自己还没有很好掌握 Greedy 的求解。
本题思路参考 [LeetCode] Gas Station, 喜刷刷.