加油站

力扣题目链接(opens new window)

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

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

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -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 = [2,5,2,3,5]
  • cost = [1,2,8,2,4] 为例

如图所示,我们可以先将到达每个下标时的剩余油量计算出来

开始时,我们在下标0处的加油站补充2的汽油,走到该位置需要消耗1的汽油,因此此时剩余油量为1

接下来,走到下标1处的加油站补充5的汽油,走到该位置需要消耗2的汽油,因此此时剩余油量为1 + 5 - 2 = 4

同理计算出行驶到的每个位置的剩余油量

此时不难发现,如果从下标0出发的话,到下标2时剩余油量已经不够了

所以不能从下标0出发

而从下标3出发似乎可以恰好走完一圈,在下标2处没油然后停止

这里的规律就是:计算出所有位置的油耗,然后我们从油量变为负数的位置之后的一个位置出发,就可以走完一圈

用贪心的方式描述就是:

局部最优:使用一个变量curGasSum累加行驶到当前位置的油量剩余,一旦该变量小于0,假设当前位置为i,那么下一次的起始位置至少要是i+1,因为从i之前开始一定不行。

全局最优:找到一定可以跑完一圈的起始位置

代码

步骤如下:

1、定义变量

  • 统计行驶到当前位置的油量剩余
  • 统计遍历过程中的所有油量(可能为负值)
  • 记录开始行驶的位置

2、遍历下标位置(相当于遍历加油站,只是下标和gas一样)

3、分别计算当前剩余油量和总油量

4、判断当前油量是否为负(遇到负数油量,说明该位置之前的位置都不可能支撑走完一圈,要从该位置之后开始走)

  • 更新出发位置到负值的后一位
  • 重置当前油量curGasSum

5、判断totalGas是否为负(如果遍历完所有可能出发的下标后,油耗为负数,则说明从哪走都不行,直接返回-1)

class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
//定义一些变量
int curGasSum = 0;//统计行驶到当前位置的油量剩余
int totalGas = 0;//统计遍历过程中的所有油量(可能为负值)
int beginIndex = 0;//开始行驶的位置,即出发位置
for(int i = 0; i < gas.size(); ++i){//遍历gas(相当于遍历加油站,只是下标和gas一样)
curGasSum += gas[i] - cost[i];//当前剩余油量
totalGas += gas[i] - cost[i];//需要分开计算
if(curGasSum < 0){//遇到负数油量,说明该位置之前的位置都不可能支撑走完一圈,要从该位置之后开始走
beginIndex = i + 1;//更新出发位置
curGasSum = 0;//重置当前油量
}
}
if(totalGas < 0) return -1;//如果遍历完所有可能出发的下标后,油耗为负数,则说明从哪走都不行
return beginIndex;
}
};

【LeetCode贪心#06】加油站(股票买卖变种)的更多相关文章

  1. [LeetCode] Gas Station 加油站问题

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...

  2. Gas Station|leetcode 贪心

    贪心:尽量将gas[i]-cost[i]>0的放在前面,gas[i]-cost[i]<0的放在后面.(路程的前面有汽油剩下,耗汽油的放在路程的后面). 能否全程通过的 条件 是:sum(g ...

  3. 【leet-code】135. 加油站

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

  4. [Leetcode 134]汽车加油站 Gas Station (环形)

    [题目] There are N gas stations along a circular route, where the amount of gas at station i is gas[i] ...

  5. Leetcode 贪心 Best Time to Buy and Sell Stock

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie Best Time to Buy and Sell Stock Total Accepted ...

  6. leetcode 贪心算法

    贪心算法中,是以自顶向下的方式使用最优子结构,贪心算法会先做选择,在当时看起来是最优的选择,然后再求解一个结果的子问题. 贪心算法是使所做的选择看起来都是当前最佳的,期望通过所做的局部最优选择来产生一 ...

  7. [LeetCode]LCP 06. 拿硬币

    桌上有 n 堆力扣币,每堆的数量保存在数组 coins 中.我们每次可以选择任意一堆,拿走其中的一枚或者两枚,求拿完所有力扣币的最少次数. 示例 1: 输入:[4,2,1] 输出:4 解释:第一堆力扣 ...

  8. 【LeetCode贪心#09】用最少数量的箭引爆气球(涉及区间重叠情况判断)

    用最少数量的箭引爆气球 力扣题目链接(opens new window) 在二维空间中有许多球形的气球.对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标.由于它是水平的,所以纵坐标并不重 ...

  9. 【LeetCode贪心#12】图解监控二叉树(正宗hard题,涉及贪心分析、二叉树遍历以及状态转移)

    监控二叉树 力扣题目链接(opens new window) 给定一个二叉树,我们在树的节点上安装摄像头. 节点上的每个摄影头都可以监视其父对象.自身及其直接子对象. 计算监控树的所有节点所需的最小摄 ...

  10. leetcode: 贪心

    1. jump game Given an array of non-negative integers, you are initially positioned at the first inde ...

随机推荐

  1. [转帖]【k8s】1、基础概念和架构及组件

    文章目录 一.kubernetes概述 1.什么是kubernetes? 2.应用程序部署方式的演变 3.为什么要用kubernetes? 二.kubernetes 特性 三.Kubernetes集群 ...

  2. SQLSERVER 标准版与企业版的版本标识区别

    1.  windows 标准版  sqlserver 标准版 2. Windows 数据中心版 sqlserver 企业版 3. Win10 之后 服务器版本缩减的很厉害 只有两个版本了 如图示 4. ...

  3. 一招轻松解决node内存溢出问题

    node启动项目造成内存溢出的解决办法 我们在使用node启动项目的时在项目较大的时候,可能会造成内存溢出.为什么会造成内存溢出呢? 要回答上面这个问题,我们要了解node中是如何分配内存的. Nod ...

  4. vue3中beforeRouteEnter 的使用和注意点

    beforeRouteEnter 在vue3中的使用 有些时候,我们需要在知道是从哪一个页面过来的. 然后做一些逻辑处理 比如说:从A->B,B页面需要调用接口,回填B页面中的数据 B--> ...

  5. 【小测试】VictoriaMetrics中如何汇总单个time series上的多个data point?

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 问题最终在andy专家的帮助下解决,但是内部的原理还是很迷 ...

  6. 微信对话平台API开发

    接入官方文档接入文档 下面我们开始使用前端来进行接入 <!DOCTYPE html> <html> <head> <meta charset="UT ...

  7. 从零开始配置 vim(14)——目录管理插件

    我们在介绍vim目录管理的时候提到 vim自带一个 叫做 netrw的工具来管理目录.但是它自身的功能有限,而且样式也丑.今天我们将使用其他强大的插件来替代 netrw,增强目录管理功能 nvim-t ...

  8. 基于Hyper-V搭建免费桌面云

    Hyper-V 是 Microsoft 的硬件虚拟化产品. 它用于创建并运行计算机的软件版本,称为"虚拟机". 每个虚拟机都像一台完整的计算机一样运行操作系统和程序. 如果需要计算 ...

  9. Hbase简单介绍

    一.背景介绍 我们生活在一个互联网的时代,这个时代的特点是,无论任何事情,只要我们想知道,都可以通过互联网迅速的检索到问题的答案,并且答案是有用的,并非常切合我们的需要. 因此,很多公司都开始致力于提 ...

  10. 零基础入门学习Java之多线程

    多线程 话不多说,看代码 1.什么是多线程 众所周知CPU单线程的东西,也就是说在同一时间内程序只能去做一件事情,但很多时候比如说多人买票.龟兔赛跑.游戏开发等都需要在同一时间内完成多个东西,因此就有 ...