【Classic 150 刷题计划】 LeetCode 134. 加油站 | C++ 贪心算法与局部否决逻辑

LeetCode 134. 加油站

📌 题目描述

题目级别:中等

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gascost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

  • 示例 1:
    输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
    输出: 3

💡 破题思路:贪心算法 (一次遍历)

如果使用暴力解法,枚举每个节点为起点去模拟跑一圈,时间复杂度是 O(N2)O(N^2)O(N2),会超时。

事实上,我们可以通过推导得出两个极其强大的结论,从而将复杂度降为 O(N)O(N)O(N):

  1. 总和 >= 0 必有解

    如果整条环路的总油量 sum(gas) 大于等于总消耗 sum(cost),那么一定存在一个起点能够跑完一圈。所以我们需要一个变量 tolGas 来记录全局的净油量,只要遍历结束后 tolGas >= 0,我们就放心大胆地返回计算出的起点。

  2. 局部亏损引发的连坐否决

    假设我们从起点 i 出发,一路开到了节点 j,但在准备前往 j+1 时发现油箱里的油变负数了。

    这不仅仅意味着 i 不能作为起点,更意味着从 ij 之间的任何一个节点都不能作为起点!

    为什么?因为我们从 i 能够开到中间的节点 k,说明到达 k 时油箱里多多少少带着点剩余的油。带着剩余的油从 k 出发最终都倒在了 j,如果你清空油箱直接从 k 重新出发,绝对会死得更早。

    贪心策略 :一旦在节点 jcurGas < 0,直接将下一次尝试的起点跳跃到 j + 1,并将 curGas 清零重新累加。


💻 C++ 代码实现 (原汁原味作者版)

cpp 复制代码
class Solution {
public:
    int canCompleteCircuit(std::vector<int>& gas, std::vector<int>& cost) {
        int n = gas.size();
        
        // 记录从当前起点 st 出发后的局部净油量
        int curGas = 0;
        // 记录跑完全程的全局净油量
        int tolGas = 0;
        // 记录潜在的起点
        int st = 0;
        
        for (int i = 0; i < n; i ++ )
        {
            tolGas += gas[i] - cost[i];
            curGas += gas[i] - cost[i];

            // 一旦局部油量跌破 0,触发"连坐否决"
            if (curGas < 0)
            {
                curGas = 0; // 油箱清空,从下一个站重新开始计算
                st = i + 1; // [st, i] 区间内的所有站点全军覆没,新起点只能是 i + 1
            }
        }
        
        // 只要全局油量 >= 0,最终锁定下来的 st 就绝对是合法的
        return tolGas >= 0 ? st : -1;
    }
};
相关推荐
夜不会漫长1 小时前
C++:类和对象(1)
java·开发语言·c++
6Hzlia1 小时前
【Classic 150 刷题计划】 LeetCode 274. H 指数 | C++ 二分答案法 (单调性降维打击)
c++·算法·leetcode
码匠许师傅2 小时前
【C++三方组件】nlohmann/json:像写 STL 一样操作 JSON
c++
Yingye Zhu(HPXXZYY)2 小时前
洛谷B4337 [中山市赛 2023] 简单数学题
c++·算法
郝学胜-神的一滴2 小时前
C++11 工程级应用 12:编译期类型魔法,干掉重复与臃肿的代码
开发语言·数据结构·c++·软件工程·visual studio
m0_734571762 小时前
深入理解C++ 析构函数<四>虚析构函数
开发语言·c++
青山木3 小时前
枚举类DP进阶:完全平方数与零钱兑换
java·数据结构·算法·leetcode·动态规划
学习智者3 小时前
《玄》IDE v3.8.2重磅发布:数据外置+全链路优化
开发语言·c++·ide·中文语言 玄