每日算法练习:LeetCode 134. 加油站 ✅
大家好我是你们的算法小伙伴。今天我们来练习一道经典的贪心算法题目 ——LeetCode 134. 加油站。这道题考察在环形路径中寻找可行起点是面试中非常典型的 “贪心选择” 问题。题目描述在一条环路上有n个加油站其中第i个加油站有汽油gas[i]升。你有一辆油箱容量无限的汽车从第i个加油站开往第i1个加油站需要消耗汽油cost[i]升。你从其中的一个加油站出发开始时油箱为空。给定两个整数数组gas和cost如果你可以按顺序绕环路行驶一周则返回出发时加油站的编号否则返回-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.length1 n 10^50 gas[i], cost[i] 10^4输入保证答案唯一。解题思路核心前提判断首先我们可以快速判断是否存在解如果总汽油量 总消耗量即sum(gas) sum(cost)则一定无法绕一圈直接返回-1。只有当sum(gas) sum(cost)时才一定存在唯一解。贪心算法核心思想我们不需要枚举所有起点只需要一次遍历即可找到答案维护两个变量currentTank当前油箱的剩余油量。start当前候选的起点加油站初始为0。遍历每个加油站计算当前加油站的净油量diff gas[i] - cost[i]。currentTank diff。如果currentTank 0说明从start到i这段路无法走完起点必须更新为i1并重置currentTank 0。遍历结束后start就是唯一的可行起点。关键逻辑解释如果从start出发走到i时油箱变空说明start到i之间的所有点都不能作为起点否则会更早油箱为空。下一个可能的起点只能是i1。因为总油量足够所以最终的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 模拟示例 1gas [1,2,3,4,5],cost [3,4,5,1,2]表格igas[i]cost[i]difftotalGascurrentTankstart 变化013-2-2-2start1, currentTank0124-2-4-2start2, currentTank0235-2-6-2start3, currentTank03413-33不变452306不变totalGas 0 0存在解。最终start 3与示例结果一致。复杂度分析时间复杂度O (n)仅遍历数组一次。空间复杂度O (1)仅使用常数级额外空间。总结快速判断先算总油量和总消耗不足直接返回-1。贪心选择一次遍历遇到油箱不足就更新起点保证最终找到唯一可行解。核心逻辑如果一段路走不通这段路的所有点都不能作为起点下一个可能的起点只能是这段路的下一个点。这道题是贪心算法中 “跳过无效区间” 的经典应用代码简洁高效是面试必背模板。今天的每日算法练习就到这里我们明天再见
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2439418.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!