news 2026/4/15 12:10:54

贪心算法专题(八):绝处逢生的起点——「加油站」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
贪心算法专题(八):绝处逢生的起点——「加油站」

哈喽各位,我是前端小L。

欢迎来到贪心算法专题第八篇!

题目描述很长,但核心很简单:

有一些加油站围成一个圈。

  • gas[i]:第i站有多少油。

  • cost[i]:从第i站开到第i+1站要耗多少油。

  • 你有一辆油箱无限大的车。

  • 目标:找一个起点,让你能绕圈跑完一周。如果找不到,返回 -1。

力扣 134. 加油站

https://leetcode.cn/problems/gas-station/

题目分析:

  • 输入:两个整数数组gascost

  • 输出:起始加油站的下标(唯一解)。

例子:

gas = [1, 2, 3, 4, 5]

cost = [3, 4, 5, 1, 2]

  • 从下标 3(油4,耗1)出发:

    • 到下标 4:剩 3,加 5,剩 8。耗 2。

    • 到下标 0:剩 6,加 1,剩 7。耗 3。

    • ... 一路顺风。返回 3。

核心思维:归零与跳跃

首先,有一个全局的硬性条件:

如果所有站点的总油量 sum(gas) 小于总消耗 sum(cost),那神仙也跑不完一圈。 直接返回 -1。

接下来是贪心的核心逻辑:局部最优推导。

我们维护一个 curSum(当前油箱余额)。

假设我们需要从 i 站出发。

  1. 我们计算gas[i] - cost[i],这是这一站的净剩油量

  2. 我们累加这个净剩量到curSum

  3. 如果curSum < 0

    • 说明车在这一站(假设是j)抛锚了。

    • 关键推断:从ij之间的任何一个站点k,都不可能作为起点!

    • 为什么?因为如果你从i出发,到达k时,你的油箱里一定有>= 0的油(否则你早在k之前就抛锚了)。带着这些“遗产”油你都在j站死掉了,如果你直接从k站白手起家(初始油量为0),你在j站只会死得更惨!

    • 策略:既然ij都不行,那我们就把起点设为j + 1,并把curSum归零,重新开始尝试。

[图解逻辑:A -> ... -> B (死) => 起点直接跳到 B+1]

算法流程

  1. 初始化:

    • curSum = 0:当前连续路段的累积剩余油量。

    • totalSum = 0:全局的总剩余油量(用于最后判断是否有解)。

    • start = 0:我们假设的起点。

  2. 遍历所有加油站i

    • 计算当前站的净收益:rest = gas[i] - cost[i]

    • totalSum += rest

    • curSum += rest

    • 贪心判断:如果curSum < 0

      • 说明从starti这段路走不通。

      • 更换起点start = i + 1

      • 重置当前累积curSum = 0

  3. 最终判断

    • 循环结束后,如果totalSum < 0,说明总油不够,返回 -1。

    • 否则,返回我们最后确定的start。(只要总油够,且我们找到了一段路能一直走到终点,那么数学上可以证明,从这个start绕回前面的路也是通的)。

代码实现 (C++)

C++

#include <vector> using namespace std; class Solution { public: int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { int curSum = 0; int totalSum = 0; int start = 0; for (int i = 0; i < gas.size(); i++) { // 计算当前站点的净剩油量 int rest = gas[i] - cost[i]; totalSum += rest; curSum += rest; // 贪心策略:如果累积油量小于0,说明从 start 到 i 的区间无法连通 if (curSum < 0) { // 之前的努力全部作废,起点重置为下一个点 i + 1 start = i + 1; // 油箱归零 curSum = 0; } } // 全局判断:如果总油量不够总消耗,肯定无解 if (totalSum < 0) { return -1; } // 否则,最后确定的 start 就是唯一解 return start; } };

深度复杂度分析

  • 时间复杂度:O(N)

    • 我们只需要遍历一次数组。

    • 这比暴力法的 $O(N^2)$ 简直是质的飞跃。

  • 空间复杂度:O(1)

    • 只需要几个变量。

总结:相信数学,相信贪心

这道题最难理解的地方在于:为什么 totalSum >= 0 且 curSum 在最后一段非负,就一定能保证绕圈成功?

这涉及到一个数学证明:如果总和非负,那么一定存在一个起点,使得所有前缀和非负。我们通过贪心策略抛弃了所有“前缀和为负”的区间,剩下的那个起点,就是那个“天选之子”。

贪心算法在这里表现为:遇到困难(负数),立刻止损,跳过整段困难区间,寻找新的希望。


下一题预告:分发糖果

接下来这道题是贪心算法的Hard级别题目,也是面试中的“终极杀手”。

  • 一群孩子排排坐,每个孩子有评分。

  • 每个孩子至少一颗糖。

  • 相邻的孩子,评分高的必须获得更多的糖果。

  • 问最少需要多少糖?

这道题难就难在“相邻”是双向的(既要比左边多,又要比右边多)。

贪心策略教我们:不要试图同时顾及两边! 我们可以先从左往右遍历一次(只顾左边),再从右往左遍历一次(只顾右边),最后取最大值。

准备好分糖果了吗?下期见!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/13 10:18:09

深度学习环境搭建太难?试试PyTorch-CUDA-v2.7一体化镜像

深度学习环境搭建太难&#xff1f;试试PyTorch-CUDA-v2.7一体化镜像 在深度学习项目启动阶段&#xff0c;你是否也经历过这样的“至暗时刻”&#xff1a;明明代码写得飞快&#xff0c;却卡在环境配置上整整两天&#xff1f;ImportError: libcudart.so.12 not found、CUDA drive…

作者头像 李华
网站建设 2026/4/15 11:06:02

Git Commit规范在AI项目中的应用:配合PyTorch-CUDA环境管理代码

Git Commit规范在AI项目中的应用&#xff1a;配合PyTorch-CUDA环境管理代码 在深度学习项目的实际开发中&#xff0c;一个看似微小的提交信息——比如“fix bug”或“update code”——可能在几个月后成为团队追溯实验失败根源时的最大障碍。更常见的是&#xff0c;当某位同事…

作者头像 李华
网站建设 2026/4/11 13:52:48

PyTorch版本混乱?锁定PyTorch-v2.7稳定版本镜像

PyTorch版本混乱&#xff1f;锁定PyTorch-v2.7稳定版本镜像 在深度学习项目开发中&#xff0c;你是否经历过这样的场景&#xff1a;刚从同事那里拿到一份训练脚本&#xff0c;满怀信心地运行 python train.py&#xff0c;结果却弹出一行红色错误&#xff1a; ImportError: li…

作者头像 李华
网站建设 2026/4/15 11:06:09

人工智能应用-机器视觉:车牌识别(3)

​​​​​​车牌定位 -基于图像处理的传统方法早期的车牌识别系统主要基于人工设计的图像处理流程&#xff0c;利用车牌具有固定颜色、形状和文字排列的特点&#xff0c;通过一系列预处理操作完成定位。一套典型流程如下&#xff1a;灰度化&#xff1a;将彩色图像转换为灰度图…

作者头像 李华
网站建设 2026/4/15 11:06:09

git clone后直接运行!PyTorch-CUDA-v2.7镜像内置完整依赖

PyTorch-CUDA-v2.7 镜像&#xff1a;克隆即运行的深度学习环境革命 在AI项目开发中&#xff0c;你是否经历过这样的场景&#xff1f;刚拿到同事分享的模型代码&#xff0c;兴冲冲地准备复现实验结果&#xff0c;却卡在了第一步——环境配置。torch not found、CUDA version mis…

作者头像 李华
网站建设 2026/4/15 11:06:18

PyTorch-CUDA-v2.7镜像支持多卡并行,大幅提升模型训练效率

PyTorch-CUDA-v2.7镜像支持多卡并行&#xff0c;大幅提升模型训练效率 在当今AI研发的日常中&#xff0c;一个令人熟悉的场景是&#xff1a;算法工程师花费数小时甚至一整天&#xff0c;只为配置好PyTorch环境——CUDA版本不匹配、cuDNN安装失败、驱动冲突……而当终于跑通代码…

作者头像 李华