134 Gas Station

LeetCode 134 加油站问题解析
本文解析了LeetCode上编号为134的加油站问题,阐述了解决该问题的一种高效算法思路,并提供了Python代码实现。通过巧妙地避免重复计算,将时间复杂度降低至线性级别。

# 134 Gas Station

题目来源:

 https://leetcode.com/problems/gas-station/description/

题意分析:

N个气站围成了圈,每个气站有gas[i],你有一辆车可以从任一气站出发,从气站i出发到i+1需要消耗气cost[i],问能否从任一气站出发,保证车中途气不用完且能回到起点。可以的话输出起点坐标,否则输出-1.

题目思路:

显而易见的是如果sum(gas)<sum(cost),是不可能走完的。

最简单的想法,就是以每个气站为起点,遍历一次,找到那个唯一解。时间复杂度为O(n^2)n为气站数目。

然后我们发现一个定理:

如果我们从第i个气站出发,第一个不能到达的气站Indexj,那么从第i+1..j-1个气站出发也不能到达第j个气站。

证明如下:

以从第i+1气站出发为例,从第i气站出发到达第i+1气站后剩余的气>=0,再从i+1出发,仍然到达不了第j气站。从第i+1气站出发的话开始剩余的气为0,比上述的情况要糟糕,所以也到达不了第j气站。i+2..j-1个气站出发同理,第i气站到达出发点时剩余的气>=0

所以我们可以实现气站的跳跃,从0气站出发,一旦发现到达j+1气站后剩余的气<0(sum+gas[j]-cost[j]<0),即不能到达j+1气站,就从j+1气站重新出发。因为题目保证具有唯一解,所以只需要记录最后的出发点k即可。k前面的点肯定不行,k后面的点如果是解,那k可以到达后面的点,那么k也是解,与具有唯一解矛盾,所以该出发点为唯一解。

代码:

1. class Solution:  

2.     def canCompleteCircuit(self, gas, cost):  

3.         """ 

4.         :type gas: List[int] 

5.         :type cost: List[int] 

6.         :rtype: int 

7.         """  

8. #         diff=[0]*len(gas)  

9. #         for i in range(0,len(gas)):  

10. #             diff[i]=gas[i]-cost[i]  

11.           

12. #         for i in range(0,len(diff)):  

13. #             if (diff[i]>=0):  

14. #                 if (self.travel(diff,i)):  

15. #                     return i  

16. #         return -1  

17.                   

18. #     def travel(self,diff,pos):  

19. #         left=0  

20. #         for i in range(0,len(diff)):  

21. #             left=left+diff[(i+pos)%len(diff)]  

22. #             if (left<0):  

23. #                 return False  

24. #         return True  

25.           

26.         sum=0  

27.         res=0  

28.         total=0  

29.         for i in range(len(cost)):  

30.             sum=sum+gas[i]-cost[i]  

31.             if (sum<0):  

32.                 total=total+sum  

33.                 sum=0  

34.                 res=i+1  

35.                   

36.         total=total+sum;  

37.         return -1 if total<0 else res  

 

提交细节:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值