题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/gas-station
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一起来读题(中英对照)

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

There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i].
(解析:there be sth 句型表示某个地方有某个东西,这是我们都知道的。那说点不是所有人都知道的 [赶紧说啊你废话这多 ],其实在英语中 be 可以理解为 live ,即 be 可以代表存在的意思,这在某些大家可能不太理解的 there be 句型中有关键作用。along 介词,表示沿着的意思,a circular route 一个圆形路线或者一个环形路线,where 后面的宾语从句解释了 route 路线上的情况,at the ith 在第i个加油站上,the amount of gas 汽油量是 gas[i])

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

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i + 1)th station. You begin the journey with an empty tank at one of the gas stations.
(解析:car with … 这里的 with 介词理解为带有某种状态,即一量有着 … 状态的车,tank 坦克,箱子,这里 gas tank 显然是汽油箱;这里 and 连接两个句子,前面是 you have a car ,你有一个无限汽油容量的车,后面是 it costs … to do sth ,即从第 i 站到下一站第 i + 1 站消耗 cost[i] 的汽油。you begin … with… 这里的 with 再次表示带有某种状态)

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

Given two integer arrays gas and cost, return the starting gas station’s index if you can travel around the circuit once in the clockwise direction, otherwise return -1. If there exists a solution, it is guaranteed to be unique
(解析:arrays 数组,travel around 走一圈,同义词traverse也有遍历的意思,clockwise direction,clock 时钟,很明显这个单词意思是顺时针方向。unique 很常见了,唯一的,即答案保证唯一)

解法一 单调队列 O(n)

【解法来自 ACWING 题号 1088】

第一步:破环成链,把环形通过数组重复一遍,出去环形结构,变成链的结构(更多是方便画图,方便理解,其实不用这样也行)
第二步:使用一个单调队列保存状态,我们要求能否走完一个环,等价问题是这个环上的每个节点存油量大于等于0。每个节点的存油量大于等于0等价于存油量最低的点油量大于等于0。

那我们遍历一次我们破环成链后的数组,向后(正序)向前(逆序)都可以。

第三步:因为要走一圈,所以只有当 n 个点的状态我们已经保存到单调队列中,才可以进行后续判断。所以不论正序逆序,都要再第二次遍历时才能进行判断。
第四步:每次判断,由于我们第一次遍历保存了所有点的状态, 第二次遍历的过程中判断最小值是否大于等于0时,某些点不能使用,因为他可能使得我们的路径大于一圈,例如假如单调队列第一个最小值(维护最小值还是最大值根据我们遍历顺序而定,这里逆序遍历,我们维护的是最小值)是 index=0 的节点,那我们判断 index=2 的点出发能否走一圈时,显然不能使用单调队列头部的值。假如我们判断 index=i 的点能否顺时针走一圈,那么从 index=i 开始,一直到 index=i+n-1 ,总共 n 个点,走完了一圈,所以我们单调队列头部的值的 index 取值范围是 [i + n - 1 % n, i] 或者 [i, i + n - 1]。因为我们遍历是有顺序的,当 index 不满足条件直接 pop 扔掉使用后面的值即可。
第五步:每次判断,我们使用前缀和快速计算某个范围的和,即从 index=i 的点走到单调队列头部 index=x 的那个点时,汽油存量。然后判断它是否大于 0 即可。

Q1:单调队列保存的是什么状态?
A:显然我们不能直接保存汽油存量,因为从哪个点触发不确定,那么该点的存量也不能直接求的,如果可以直接求的,显然我们也不必这么麻烦。还记得我们提到,使用前缀和快速求和,我们虽然不能直接保存存量,但是我们可以保存破环成链之后,某一点的前缀和,在这个线性结构中就可以通过前缀和做差快速的求出从当前需要判断的点 index=i 出发,到单调队列 index=x 的点时剩余的汽油量。然后就可以判断这个最小值是否大于等于0。

class Solution {public:#define X_TYPE intconst int N = 1e5 + 10;typedef long long LL;vector<int> gas = vector<int> (N, 0);vector<int> cost = vector<int> (N, 0);vector<X_TYPE> s = vector<X_TYPE> (N << 1, 0);vector<X_TYPE> que = vector<X_TYPE> (N << 1, 0);int canCompleteCircuit(vector<int>& _gas, vector<int>& _cost) {int n = _gas.size();int hh = 0, tt = -1;int ans = -1;// vector<bool> ans = vector<bool> (n, false);for (int i = 1; i <= n; ++ i) {gas[i] = _gas[i - 1];cost[i] = _cost[i - 1];s[i] = s[i + n] = gas[i] - cost[i];}for (int i = 1; i <= n << 1; ++ i) s[i] += s[i - 1];for (int i = n << 1; i; i --) {while (hh <= tt && que[hh] > i + n - 1) hh ++;while (hh <= tt && s[que[tt]] >= s[i]) tt --;que[++ tt] = i;if (i <= n && s[que[hh]] - s[i - 1] >= 0) {ans = i - 1;break;}}return ans;}
};

解法二 枚举 + 优化 O(n)

简单的枚举每个点能否走一圈,当起点 i 到达 起点 j 之后,下一站无法到达 j + 1,那么 [i, j] 之间任意一点 k 都无法到达 j + 1。因为从 i 开始,到达 k,此时剩余油量大于等于0(不加 k 点的油量),但这种情况下都无法到达 j + 1。如果让 k 作为起点,那么意味着此时只有 k 点的油,那么肯定是无法到达 j + 1 的。
从 i 到 k,k 点时的油量 = 前面的剩余油量(>= 0)+ k 点的油量。无法到达 j + 1。
k 作为起点,k 点时的油量 = k 点的油量,显然更不可能到达 j + 1。
所以下次枚举直接从 j + 1 开始即可。

class Solution {public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int n = gas.size();for (int i = 0, j; i < n; ) {// 枚举每个点 iint left = 0;for (j = 0; j < n; ++ j) {// 枚举从 i 开始向前走int k = (i + j) % n;// 补油再尝试向前走left += gas[k] - cost[k];if (left < 0) break;}// 等于 n 说明走完了 n 个点if (j == n) return i;// 否则 i 到 i + j 都不行,只能从 i + j + 1 枚举i = i + j + 1;}return -1;}
};

LeetCode 134 加油站 全面详细题解【持续更新所有解法】相关推荐

  1. HDU杭电OJ经典100题2000-2099_Java版详细题解(持续更新)

    今年寒假打算用Java把杭电2000-2099全部AC(现在持续更新),如下是题目链接,之后是我的题解,全部做完后我会把所有AC的题解打包上传的 题号 题名 题号 题名 2000 ASCII码排序 2 ...

  2. leetcode贪心算法题集锦(持续更新中)

    leetcode贪心算法题集锦 leetcode贪心算法题集锦(持续更新中).python 和C++编写. 文章目录 leetcode贪心算法题集锦 一.贪心算法 1.盛最多水的容器 2.买股票的最佳 ...

  3. Leetcode 134. 加油站 解题思路及C++实现

    方法一:直接暴力方法 解题思路: 当 gas[i] >= cost[i] 时,这个加油站才可能是个出发点,遍历gas容器(数组),当出现 gas[i] >= cost[i] 时,看看以这个 ...

  4. 用java写一个汽车加油的程序_Java实现 LeetCode 134 加油站

    134. 加油站 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升 ...

  5. [LeetCode] [C++] 第一轮刷题总结(持续更新~~~)

    LeetCode 解题报告 LC_1_解题报告 LC_2_解题报告 LC_3_解题报告 LC_4_解题报告 LC_5_解题报告 LC_6_解题报告 LC_7_解题报告 LC_206_解题报告 LC_2 ...

  6. LeetCode面试必刷题目总结 持续更新中...

    说明 文章源地址:sanzo.top/#/post/算法与数据结构/算法题 多数元素 题目链接 找到数组中众数(出现次数>⌊n2⌋>\lfloor\frac{n}{2}\rfloor> ...

  7. leetcode 134. 加油站 思考分析

    目录 题目 1.暴力法,双层遍历 2.贪心 题目 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站 ...

  8. LeetCode 134. 加油站(贪心)

    文章目录 1. 题目 2. 解题 1. 题目 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要 ...

  9. Jarvis OJ PWN题解 持续更新~

    最近沉(被)迷(迫)学pwn    看我们的志琦大佬 我就知道  pwn 玩玩就行    但是 不认真学 不行 然后向大佬打听了几个pwn的平台网站 打算 玩一下   这里找到了 Jarvis OJ ...

最新文章

  1. huffman树和huffman编码
  2. C# JSON使用过程中开发的小工具
  3. 如何做自己的服务监控?spring boot 1.x服务监控揭秘
  4. ES5中新增的Array方法详细说明
  5. 乐高(LEGO)在线购物店面剖析
  6. CPtrArray、CObArray类
  7. 如何检查私钥和公钥是否配对_如何检查家具是否有臭虫
  8. body 没有被撑开_父div没有被撑开,该怎么解决?_html/css_WEB-ITnose
  9. 跨国际日期分界线的解决方法
  10. localhost可以访问 ip不能访问_如何解决域名可以访问80端口但访问不了其他端口的问题...
  11. Salesforce:下个财年营收我们有望突破100亿美元
  12. MongoDB下载(速度较快操作)
  13. 360软件小助手-壁纸存储路径
  14. MATLAB画图符号标注
  15. 进入MySQL目录下的bin文件夹
  16. 懒虫读诗 (树形dp+分组背包)
  17. 用Python下载Lofter上“喜欢”的文章和图片
  18. python爬取17000个球员_Python爬取NBA球员生涯数据及简单可视化
  19. Java导出excel表格,数字数据带E
  20. FireFox必备插件(七)

热门文章

  1. java 流 flush_Java OutputStream.flush()清空输出流
  2. vivo的android是什么手机,酷派回归了!或成OPPO、vivo最大劲敌,2021安卓“机皇”会是谁?...
  3. 事业单位计算机技术岗位中级职称,事业单位技术岗能从11级直接转9级吗?
  4. 【PS/AI】2021新年祝福海报牛年模板素材
  5. U盘在自己电脑上打不开,别人电脑上却可以打开
  6. 2020-09-13猜人名小游戏原代码万门大学Python课程(https://www.wanmen.org/courses/5f0e60a93b71b90206008309/lectures/5f)
  7. 台式计算机防盗锁怎么安装,笔记本防盗锁,小编教你笔记本防盗锁怎么用
  8. 小米笔记本pro macOS Mojave使用体验
  9. python爬虫代理服务器_Python爬虫多线程抓取代理服务器
  10. node Express.js node:internal/modules/cjs/loader:988 throw err; ^ Error: Cannot find module ‘