当前位置: 首页 > news >正文

每日算法练习:LeetCode 134. 加油站 ✅

大家好,我是你们的算法小伙伴。今天我们来练习一道经典的贪心算法题目 ——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 解释: 从 3 号加油站出发,可获得 4 升汽油。油箱 = 0 + 4 = 4 开往 4 号加油站:4 - 1 + 5 = 8 开往 0 号加油站:8 - 2 + 1 = 7 开往 1 号加油站:7 - 3 + 2 = 6 开往 2 号加油站:6 - 4 + 3 = 5 开往 3 号加油站:5 - 5 = 0,正好回到起点。

示例 2:

输入: gas = [2,3,4], cost = [3,4,3] 输出: -1 解释: 无法绕环路行驶一周。

提示:

  • n == gas.length == cost.length
  • 1 <= n <= 10^5
  • 0 <= gas[i], cost[i] <= 10^4
  • 输入保证答案唯一。

解题思路

核心前提判断

首先,我们可以快速判断是否存在解:

  • 如果总汽油量 < 总消耗量(即sum(gas) < sum(cost)),则一定无法绕一圈,直接返回-1
  • 只有当sum(gas) >= sum(cost)时,才一定存在唯一解。

贪心算法核心思想

我们不需要枚举所有起点,只需要一次遍历即可找到答案:

  1. 维护两个变量:
    • currentTank:当前油箱的剩余油量。
    • start:当前候选的起点加油站,初始为0
  2. 遍历每个加油站:
    • 计算当前加油站的净油量diff = gas[i] - cost[i]
    • currentTank += diff
    • 如果currentTank < 0,说明从starti这段路无法走完,起点必须更新为i+1,并重置currentTank = 0
  3. 遍历结束后,start就是唯一的可行起点。

关键逻辑解释

如果从start出发,走到i时油箱变空,说明:

  • starti之间的所有点都不能作为起点(否则会更早油箱为空)。
  • 下一个可能的起点只能是i+1
  • 因为总油量足够,所以最终的start一定是正确解。

代码实现

class Solution { public int canCompleteCircuit(int[] gas, int[] cost) { int n = gas.length; int totalGas = 0; int currentTank = 0; int start = 0; for (int i = 0; i < n; i++) { int diff = gas[i] - cost[i]; totalGas += diff; currentTank += diff; // 如果当前油箱油量不足,说明从 start 到 i 走不通,更新起点 if (currentTank < 0) { start = i + 1; currentTank = 0; } } // 总油量 < 总消耗,无解;否则返回 start return totalGas >= 0 ? start : -1; } }

代码详解(结合示例 1 模拟)

示例 1:gas = [1,2,3,4,5],cost = [3,4,5,1,2]

表格

igas[i]cost[i]difftotalGascurrentTankstart 变化
013-2-2-2start=1, currentTank=0
124-2-4-2start=2, currentTank=0
235-2-6-2start=3, currentTank=0
3413-33不变
452306不变
  • totalGas = 0 >= 0,存在解。
  • 最终start = 3,与示例结果一致。

复杂度分析

  • 时间复杂度:O (n),仅遍历数组一次。
  • 空间复杂度:O (1),仅使用常数级额外空间。

总结

  1. 快速判断:先算总油量和总消耗,不足直接返回-1
  2. 贪心选择:一次遍历,遇到油箱不足就更新起点,保证最终找到唯一可行解。
  3. 核心逻辑:如果一段路走不通,这段路的所有点都不能作为起点,下一个可能的起点只能是这段路的下一个点。

这道题是贪心算法中 “跳过无效区间” 的经典应用,代码简洁高效,是面试必背模板。

今天的每日算法练习就到这里,我们明天再见!👋

http://www.jsqmd.com/news/520965/

相关文章:

  • 避坑指南:Matlab计算THD时容易忽略的6个细节(附采样率设置建议)
  • 告别色彩乱象:novideo_srgb如何重新定义消费级显示器色彩校准
  • Qwen3-ForcedAligner-0.6B生产环境:中小企业本地ASR服务免API调用与隐私合规方案
  • 高效掌握ControlNet-v1-1_fp16_safetensors:从入门到实践的完整指南
  • 别再复制粘贴了!手把手教你用Vite+Vue3定制专属CKEditor5编辑器(含字体、高亮、对齐插件)
  • LoRa与LoRaWAN:物联网远距离通信的“基石”与“大脑
  • tkinter绘制组件(51)——高级滑动条
  • Artisan咖啡烘焙软件:3大核心功能解密,从入门到精通的完整指南
  • TCN-GRU这个组合模型算是把时间序列预测的两个经典结构玩出了花——时间卷积负责抓局部特征,GRU来捕捉时序依赖关系。咱直接上代码看看核心部分怎么搭的
  • Whisper-large-v3在媒体行业的应用:智能字幕生成系统
  • Qwen3-0.6B-FP8部署避坑指南:新手常见问题与解决方案
  • 嵌入式系统可靠性设计七项工程实践
  • Android AOA协议嵌入式实现:裸机/RTOS兼容的USB配件模式库
  • Vibe Coding技巧-用 AI 写代码越修 Bug 越崩溃?这四步法帮你告别来回拉扯
  • 爆火全球的“小龙虾“OpenClaw:你的下一个AI管家,还是安全定时炸弹?
  • Needleman-Wunsch算法优化指南:如何用非递归方法解决多路径回溯问题?
  • STM32F103 8位并行TFT驱动库深度解析
  • SW - SW2025自带帮助文件的位置和含义
  • EcomGPT-7B模型对抗攻击与鲁棒性增强实践
  • STLink v1.8.0版本升级技术指南:从架构演进到实践落地
  • FXOS8700Q嵌入式驱动开发:9轴IMU寄存器级控制与FreeRTOS集成
  • Ubuntu下使用Docker部署Milvus及可视化工具实战指南
  • DeepSeek-R1加速秘籍:无需复杂操作,几个参数让CPU推理更快
  • SF6微水密传感器接头M12-5芯金属波纹管连接器
  • Xshell密钥免密登录Linux服务器保姆级教程(含常见问题排查)
  • GTE文本向量中文大模型保姆级教程:从部署到旅游评论分析全流程
  • 技能智能体开发:构建基于TranslateGemma的翻译Agent
  • 2603,系统调用
  • 告别断网烦恼!Android智能家居场景下的Wi-Fi双连接避坑指南
  • 突破BIM协作瓶颈:IfcOpenShell开源引擎的技术革新与实践指南