首页 > 其他分享 >【LeetCode贪心#06】加油站(股票买卖变种)

【LeetCode贪心#06】加油站(股票买卖变种)

时间:2023-03-17 13:12:11浏览次数:53  
标签:股票买卖 06 油量 gas 位置 汽油 加油站 下标 LeetCode

加油站

力扣题目链接(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;
    }
};

标签:股票买卖,06,油量,gas,位置,汽油,加油站,下标,LeetCode
From: https://www.cnblogs.com/DAYceng/p/17226258.html

相关文章

  • 代码随想录Day2-Leetcode977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
    977.有序数组的平方题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/最初想法是用二分找到恰好大于0的数;然后数组切片,负的一方反转,然后按照合并......
  • LeetCode1. 两数之和
    题目描述:给定一个整数数组nums 和一个整数目标值target,请你在该数组中找出和为目标值target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应......
  • ASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B
    编辑:llASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B型号:MIMXRT1064CVJ5B品牌:NXP/恩智浦封装:LFGBA-196批号:2023+安装类型:表面贴装型引脚数量:196类型......
  • 【leetcode】226.翻转二叉树
    翻转二叉树leetcode题目传送门题目描述思路按顺序依次交换二叉树的左右节点实现交换左右节点,递归遍历publicclassTreeNode{publicintval;......
  • LeetCode 18. 四数之和
    classSolution{public:vector<vector<int>>fourSum(vector<int>&nums,inttarget){vector<vector<int>>ans;longlongtmp=target;......
  • LeetCode1024 -- 二分
    1.题目描述查找满足劳累天数严格大于不劳累天数的最大子区间2.思路对于区间问题,很容易先想到前缀和帮助我们优化。我们可以设,劳累=\(1\),不劳累=\(-1\),那么,就是求......
  • 基于Pierre Dellacherie的俄罗斯方块-06Pierre Dellacherie算法实现
    #pragmaonce#include"Block.h"#include"Back.h"#include<limits.h>#defineLANDINGHEIGHT -45#defineROWSELIMINATED 34#defineROWTRANSITIONS -32#defin......
  • 06.深度学习--分类模型
    分类模型输入对象x,输出是这个对象属于哪一个类class,这样的应用同样有很多,比如:在金融上可以通过分类模型来决定是否贷款给某人;图像识别方面;人脸辨识方面,等等。这里依然使......
  • Leetcode202. 快乐数
    题目描述:编写一个算法来判断一个数n是不是快乐数。「快乐数」 定义为:•对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。•然后重复这个过程直到这个......
  • Codeforces Round 406 (Div. 1) C. Till I Collapse 主席树上二分
    首先贪心是显然的,但是询问有n个先考虑一个朴素的主席树做法对于每个k,对于当前固定的L,二分R,用主席树查询一下[L,R]区间内的不同数个数是否大于K个(主席树的经典应用),更新......