当前位置:网站首页>134. 加油站
134. 加油站
2022-07-22 18:03:00 【陌上小布】
题目链接
https://leetcode.cn/problems/gas-station/
一、题目描述
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
示例 1:
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 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 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。示例 2:
输入: gas = [2,3,4], cost = [3,4,3]
输出: -1
解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。提示:
gas.length == n
cost.length == n
1 <= n <= 105
0 <= gas[i], cost[i] <= 104
二、思路
1.暴力方法
暴力的方法很明显就是 O ( n 2 ) O(n^2) O(n2)的,遍历每一个加油站为起点的情况,模拟一圈。
如果跑了一圈,中途没有断油,而且最后油量大于等于0,说明这个起点是ok的。
暴力的方法思路比较简单,但代码写起来也不是很容易,关键是要模拟跑一圈的过程。
for循环适合模拟从头到尾的遍历,而while循环适合模拟环形遍历,要善于使用while!
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
for (int i = 0; i < cost.size(); i++) {
int rest = gas[i] - cost[i]; // 记录剩余油量
int index = (i + 1) % cost.size();
while (rest > 0 && index != i) {
// 模拟以i为起点行驶一圈
rest += gas[index] - cost[index];
index = (index + 1) % cost.size();
}
// 如果以i为起点跑一圈,剩余油量>=0,返回该起始位置
if (rest >= 0 && index == i) return i;
}
return -1;
}
};
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
- (提交超时)
2.贪心算法(方法一)
直接从全局进行贪心选择,情况如下:
情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的
情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。
情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能这个负数填平,能把这个负数填平的节点就是出发节点。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int curSum = 0;
int min = INT_MAX; // 从起点出发,油箱里的油量最小值
for (int i = 0; i < gas.size(); i++) {
int rest = gas[i] - cost[i];
curSum += rest;
if (curSum < min) {
min = curSum;
}
}
if (curSum < 0) return -1; // 情况1
if (min >= 0) return 0; // 情况2
// 情况3
for (int i = gas.size() - 1; i >= 0; i--) {
int rest = gas[i] - cost[i];
min += rest;
if (min >= 0) {
return i;
}
}
return -1;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)
3. 贪心算法(方法二)
首先如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。
每个加油站的剩余量rest[i]为gas[i] - cost[i]。
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,起始位置从i+1算起,再从0计算curSum。
局部最优:当前累加rest[j]的和curSum一旦小于0,起始位置至少要是j+1,因为从j开始一定不行。全局最优:找到可以跑一圈的起始位置。
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++) {
curSum += gas[i] - cost[i];
totalSum += gas[i] - cost[i];
if (curSum < 0) {
// 当前累加rest[i]和 curSum一旦小于0
start = i + 1; // 起始位置更新为i+1
curSum = 0; // curSum从0开始
}
}
if (totalSum < 0) return -1; // 说明怎么走都不可能跑一圈了
return start;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)
边栏推荐
- Shortcut keys related to idea
- MySQL binlog log
- FinClip 小程序生态构建能力升级,实现企业个性化UI定制自由
- Detailed explanation of inception audit rules
- Definition, function and brief description of wechat applet events
- VSCode代码风格笔记(Vetur)
- go :gin BasicAuth中间件
- Goldfish rhca memoirs: cl210 management storage -- realize block storage
- 【国际化】应用开发小数点和逗号
- 2022年了,该如何选择跨端技术方案呢?
猜你喜欢

【yum】yum 源的配置与使用

微信授权登录第三方APP小程序方法介绍

【微信小程序开发(三)】实现卡片的层叠滑动

微信小程序中如何正确使用本地数据缓存

If you sort the error according to the creation time field according to the framework customer management, the solution is to report an error

【机器学习】Logistic 回归(pytorch)实现

自定义炫酷效果ViewPage指示器

逻辑回归与多层神经网络的比较

The efficiency of the data warehouse system has been comprehensively improved! Data warehouse construction based on Apache Doris in Tongcheng digital Department

有手就会—如何将小程序一键打包生成App
随机推荐
Kotlin Coroutine(二):作用域及取消
【工具】几行代码就能实现复杂的 Excel 导入导出的工具类,真心强!!!
自有App小程序第三方微信授权登录的实现
AutoJS一文精通AutoJS脚本教程详解
【机器学习】线性回归PyTorch实现
【机器学习】Logistic 回归(pytorch)实现
How to correctly use local data cache in wechat applet
Explanation of contract quantification system development roadmap
【微信小程序开发】(三)首页banner组件使用swiper
卷积代码实现
【google play接入】支付服务端token获取
汇编 | 查找最大值和最小值
[开发工具]svn
微信小程序事件的定义、作用、简要说明
Zhihu DMP platform architecture construction practice based on Apache Doris
如何编写您的常见问题页面?
微信小程序中如何正确使用本地数据缓存
【深度學習】損失函數(平均絕對誤差,均方誤差,平滑損失,交叉熵,帶權值的交叉熵,骰子損失,FocalLoss)
[19:00 on July 25] Quanguo fund product roadshow: investment in Taoyuan, China
【Linux】Oracle VirtualBox安装CentOS 8