加油站环路问题

求解思路

这道题我们把环形数组想象成展开的线性数组(通过取模实现),然后用一个窗口[l, r)来表示从l站出发能走到的范围,窗口内维护一个油量累加和sum。

每次尝试让窗口右边界r向右扩展,如果加上r站的净油量(gas[r] - cost[r])后sum还是非负的,说明能走到r站,就继续扩展;

一旦发现扩展到某站会让sum变负,说明从l出发走不通,此时直接跳过整个窗口,让新起点从r+1开始尝试。

这样做的合理性在于,如果从l出发走不到r,那么从l到r之间的任何一站出发也走不到r(因为中间任何一站的初始油量都不如从l站累积过来的多),所以可以直接跳过这些站点,大大减少了尝试次数。当某个起点l的窗口成功扩展到覆盖n个站点时,就找到了答案。

代码实现

java 复制代码
public static int canCompleteCircuit(int[] gas, int[] cost) {
    int n = gas.length;
    // 窗口范围[l, r),左闭右开
    for (int l = 0, r = 0, sum; l < n; l = r + 1, r = l) {
        sum = 0;
        // 尝试扩展窗口右边界
        while (sum + gas[r % n] - cost[r % n] >= 0) {
            // 检查是否已经转了一圈
            if (r - l + 1 == n) {
                return l;
            }
            // r位置进入窗口,累加净油量
            sum += gas[r % n] - cost[r % n];
            r++;
        }
    }
    return -1;
}

如果觉得有帮助,欢迎点赞、关注、转发~

相关推荐
fengfuyao9855 分钟前
经典MUSIC算法程序以及测角精度与阵元间距、阵元数、信噪比、快拍数等的关系
算法
梦想的旅途28 分钟前
企业微信外部群消息推送实战指南
java·golang·企业微信
古城小栈11 分钟前
go-zero 从入门到实战 全指南(包的)
开发语言·后端·golang
十八岁讨厌编程22 分钟前
【算法训练营 · 补充】LeetCode Hot100(下)
算法·leetcode·职场和发展
lsx20240623 分钟前
Python 3 函数
开发语言
-To be number.wan24 分钟前
C++ 进阶技巧:如何让 cout << 自定义对象 正常输出?
开发语言·c++
独自破碎E26 分钟前
怎么实现一个滑动验证码功能?又如何防止被机器识别破解
java·spring boot·后端
2501_9444460026 分钟前
Flutter&OpenHarmony状态管理方案详解
开发语言·javascript·flutter
一路往蓝-Anbo29 分钟前
C语言从句柄到对象 (三) —— 抛弃 Malloc:静态对象池与索引句柄的终极形态
c语言·开发语言·数据结构·stm32·单片机·算法
lbb 小魔仙43 分钟前
【Java】Spring Data JPA 详解:ORM 映射、查询方法与复杂 SQL 处理
java·开发语言·sql·spring cloud