leetcode. 134. Gas Station

本文探讨了一道经典问题——加油站问题,目标是在环形路线上找到一个起点,使得汽车能够绕一圈回到起点。通过分析每个加油站的收支情况,提出了一种有效算法,能够在O(n)时间内找到解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

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 in the clockwise direction, otherwise return -1.
Note:
If there exists a solution, it is guaranteed to be unique.
Both input arrays are non-empty and have the same length.
Each element in the input arrays is a non-negative integer.

Time Limited exceed总结

再度开始刷题,遇到的这道经典的gas station,题目简明易懂,但是第一次的结果 Time Limited exceed. 看了一些discussion之后,总结如下:

  • 抓住了问题的处理核心:每个station都有一个收支,分别是gas数组和cost数组,所以gas数组和cost数组对应的每个元素的差值,就是这个station的收支。如果这个station的收支大于等于0,那么这个点是可以作为开始点的
  • 没有抓住问题的本质:一开始的思路被上面的问题核心给限制了,停留在不断的寻找收支大于0的点(简称为可用点)。私以为问题的解决方案是

首先对所有点的收支求和,如果总体的和为负,那么直接判断为-1
如果这个可用点能够到达下一个可用点,那么就这个可用点仍然为可用,否则不可用。并重复直到只剩下一个点,这个点就是start点

  • 这种解决方案虽然能够解决问题,但是太耗费时间,不够精妙

AC方案:

  • 思路:任意一个start点出发,如果start到end的收支是正数,说明你可以到达end,那么就可以将就考虑end+1这个点能不能到达;反之如果收支是负数,说明start无法到达end点,那么就考虑从start-1的能不能到达end点。一次循环,直到start和end已经考虑了整个circle
  • 代码
class Solution:
    def canCompleteCircuit(self, gas, cost):
        """
        :type gas: List[int]
        :type cost: List[int]
        :rtype: int
        """
        #得到每个位置的真是cost
        end = 0
        start = len(gas)-1
        sum = gas[start]-cost[start]

        while start>end:
            if sum >= 0:
                sum+= gas[end]-cost[end]
                end +=1
            else:
                start -=1
                sum += gas[start]-cost[start]


        return start if sum>=0 else -1
  • Discussion:这是一个贪婪问题,有的思想说,如果A无法到达B,那么AB之间的任何一个点都不能到达B,就将start直接设置为B的下一个点。略有疑惑,得到指点或自己能悟到精髓

总结:

在解这题的时候,还是抓住了一点问题的方案,但是自己的解决方案有些太死板了,开始点并不是固定的,也不是在一开始就可以确定的。应该根据收支来灵活的调整开始点和结束点。多练习开拓思维。

--------------------------------- 二次编辑分割线------------------------ --------------

解题思路:

start可以看作是一个分界点,如果start存在的话,所有的gas station的收支最终一定是大于等于0的。之所以Start能够作为起点,就是因为从start开始加的话,收支和一直是正数。

class Solution:
    def canCompleteCircuit(self, gas, cost):
        """
        :type gas: List[int]
        :type cost: List[int]
        :rtype: int
        """
        #得到每个位置的真是cost

        tank =0
        total = 0
        start =0

        for i in range(len(gas)):
            total +=gas[i]-cost[i] #计算整个数组的和
            tank += gas[i]-cost[i]#判断到点i时候的总和还是不是负数

            if tank < 0:#如果是负数,说明start之前的这一段总和为负,不满足要求,重置
                start = i+1
                tank = 0

        return start if total >=0 else -1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值