LeetCode.134. 加油站(贪心)

这段代码提供了解决LeetCode中加油站问题的算法,通过计算每个加油站的油量增量,找到能使车绕一圈回到起点的起始点。关键在于找到油量最低点后的一个加油站作为起始点。
摘要由CSDN通过智能技术生成
题解引用LeetCode用户"桔味汽水"的题解:

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int sum = 0;
        int min = Integer.MAX_VALUE;
        int minIndex = -1;
        for(int i = 0; i < gas.length; i++){
            sum = sum + gas[i] - cost[i];
            if(sum < min && sum < 0){
                min = sum;
                minIndex = i;
            }
        }
        if(sum < 0) return -1;
        return (minIndex + 1 )%gas.length;
    }
} 

这段代码是一种解决方法,用于解决“加油站”问题。该问题描述如下:有一个环形路线上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 并且距离下一个加油站的距离为 cost[i]。你有一辆油箱无限容量的车,从某一个加油站出发,开始时油箱为空。请问是否能绕路线一周,并指出从哪个加油站出发才能回到起点。

解决方法中的 `canCompleteCircuit` 函数接受两个数组:`gas`(每个加油站的汽油量)和 `cost`(从当前加油站到下一个加油站的花费)。函数的目的是找出是否存在一个起始点(加油站的索引),让你能够绕一圈回到起点。

代码分析:

1. `sum` 变量用来追踪总的油量减去总的花费。如果从某个加油站出发可以回来,那么这个 `sum` 应该是非负的。

2. `min` 变量用来记录迄今为止所见到的 `sum` 中的最小值(如果这个最小值都是非负的,意味着可以从任何加油站出发绕一圈回到起点)。

3. `minIndex` 变量记录 `min` 最小值出现时的加油站索引。

4. `for` 循环中,`sum` 累计总的油量减去总的花费,并更新 `min` 和 `minIndex`。

5. 如果 `sum` 最终是负数,这意味着车辆没有足够的油可以绕一圈回到起点,因此函数返回 `-1`。

6. 如果 `sum` 是非负的,最小油量所在的加油站的下一个加油站就是可能的起始点。所以,将 `minIndex` 加1并对 `gas.length` 取余(考虑到环形路线),得到了正确的起始索引。

该算法的基本思路是,如果从 A 点到 B 点油不够,那么从 A 和 B 之间的任何一个点出发都不可能到达 B 点。因此,只要 `sum` 相加最后非负,从 `minIndex` 的下一个位置出发,就一定可以绕一圈回到起点。

简而言之,此代码能够高效地解决加油站问题,并找出正确的起点或者确定这样的起点不存在。

在这个加油站问题的解决方案中,`(minIndex + 1) % gas.length` 这一步是计算从哪个加油站出发可以成功环绕一圈回到起点。这一计算步骤的逻辑和背后的原理如下:

### 背景

我们在遍历整个加油站数组的时候,采用的方法是计算从第 0 个加油站出发,沿途的油量净增量 `sum`(即在每个加油站的油量减去到下一个加油站的开销)。我们追踪`sum`的最小值及其对应的位置`minIndex`是因为我们想找到从哪个点出发,沿途的油量增减会最终保持非负,从而确保能绕一圈回到起点。

### 原理

1. **为什么关注`minIndex`:** 如果在某点A的`sum`是最小的,意味着从起点到A的任一点作为起始点都不可能成功绕圈,因为从任何这样的点出发,到达A之前油就会用光。因此,最佳的开始点应该是在A之后。

2. **为什么选取`(minIndex + 1) % gas.length`作为起点:** 因为如果从某个点开始,油量能持续非负直到结束(即使中间有最低点),那么从这个最低点的下一个点开始,应该也能顺利完成全程(因为此时你已经过了油量最低的点,且最终`sum`是非负的,说明油量足够)。由于数组是循环的,`minIndex + 1`可能会超过数组的边界,所以需要对数组长度`gas.length`取余,确保结果是一个有效的加油站索引。

### 示例

假设有5个加油站,经过计算得到`minIndex`为3,这意味着从加油站0出发到加油站3的过程中,在加油站3的时刻油量达到最低。这样一来,从加油站4(即`minIndex + 1`)出发的话,因为按照之前的计算,总油量够你从加油站4开到加油站3再到加油站4(环绕一圈),所以加油站4就是可行的起始点。使用取余操作是为了处理当`minIndex + 1`正好等于`gas.length`的情况,这时索引应该回到数组的开始处。

综上,`(minIndex + 1) % gas.length` 是基于上述逻辑和原理,优雅地找出了可行的起始加油站索引,确保了在有解的情况下,能够成功找到一个起始点,让汽车能够从该加油站出发绕一圈返回该加油站。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值