首页 > 其他分享 >加油站问题(贪心)

加油站问题(贪心)

时间:2024-12-11 21:33:02浏览次数:3  
标签:站点 汽油 gas 问题 加油站 cost diff 贪心

题目:

在一条环路上有 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 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。

题意:开车从某个站点出发,初始油量为 000,到达一个站点就可以补充油量,两个站点之间需要消耗油量,求从哪个站点开始能环游一圈。

汽车的油箱容量无穷,所以到达某个点时一定会将该站点的油全部加上,这是一种贪心的思想,毕竟想要全程旅游,油越多越好。

暴力的做法就是枚举起点,从它开始遍历全部站点进行尝试。站点的总数为 nnn,规定 n≤105n\leq 10^5n≤105,这种 O(n2)O(n^2)O(n2) 的操作会超时。

贪心

首先必须明确,从一个站点 iii 出发前,可以补充该站点的油量 gas[i]gas[i]gas[i];从该站点出发到达下一个站点,会消耗油量 cost[i]cost[i]cost[i]。

因此,完全可以将它们 捆绑 进行理解。环游一圈,对应 nnn 次加油与 nnn 次耗油。将 gas[i]−cost[i]gas[i]-cost[i]gas[i]−cost[i] 记为 diff[i]diff[i]diff[i]。

如果从第 iii 个站点到达第 i+1i+1i+1 个站点时,对应的 diff[i]<0diff[i]<0diff[i]<0,那就说明第 iii 个站点一定不能作为起点,因为第一段旅途都完成不了!

所以,为了方便表述 ,将 diff[i]<0diff[i]<0diff[i]<0 的第 iii 个位置看作一个“大坑”。这个坑的前面这个第 iii 点一定不能作为起点,但是再往前的站点就不一定。

结论 111:数组 diffdiffdiff 的累加和如果小于 000,一定不能完成旅途。

因为加油与耗油都是 nnn 次,加的总油量比不上消耗的,说明跨越不过全部的坑,完成不了全程。

结论 222:数组 diffdiffdiff 的累加和如果大于等于 000,一定能完成旅途。

假定一共 kkk 个坑,分布在数组的任意位置,共 kkk 个负收益与 n−kn-kn−k 个正收益。如果想要跨越难度最大,就是让所有的坑连在一起,中间不给正收益的机会。但是,只需要让起点定在 最后一个坑的后一个位置,在总累加和大于 000 的前提下,一定有正收益大于负收益,完全能旅行一圈。

思路:从头开始遍历数组,累加每一个位置的 diff[i]diff[i]diff[i],找到累加和最小的值 minminmin;接着倒序遍历数组,在 minminmin 的基础上继续累加 diff[i]diff[i]diff[i],找到让累加和为正的位置 idxidxidx,它即为答案。

这种想法就是找到负收益最大的值,为了跨越这个“大坑”,就需要找到一个位置,它的正收益足够抵消这种负面影响,从而跨越这个难题。

为什么两次遍历 方向不同

规定起点为 000 开始正向累加,负收益的值表示起点为 000 需要弥补的值。所以第二次是倒序遍历,表示让 idxidxidx 作为新的环形起点,将获得的正收益都当作油箱的起始值。

为什么这种贪心思路 正确

如果答案不存在,累加的 diffdiffdiff 值一定为负,可以直接特判结束;如果答案存在,那么这个最负的位置 minIdxminIdxminIdx,与倒序直到累加为正的位置 idxidxidx 一定满足 minIdx<idxminIdx<idxminIdx<idx。反之,他俩交叉的部分一定有正收益,不能让 minIdxminIdxminIdx 作为最负的位置,所以环形方案可行。题意确保了答案唯一,不会有第二个 idxidxidx 出现。

优点:不需要对下标进行 modmodmod 取余操作;从全局的视角出发,两次遍历的思路比较清晰。

代码如下,已附加注释:

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
       
        int curSum = 0;  // 从0行驶到i后的剩余油量
        int min = Integer.MAX_VALUE;  // 大坑的最负值
        int n = gas.length;
        for(int i = 0; i < n; i++) {
            curSum += (gas[i] - cost[i]);  // 走到第i个位置
            if(curSum < min)  // 找到从0开始最小的值--大坑
                min = curSum;
        }
if(curSum < 0)  // 说明根本就完成不了
            return -1;
        if(min >= 0)  // 说明从0出发是可行的
            return 0;
        for(int i = n - 1; i >= 0; i--) {  // 倒序遍历
            min += (gas[i] - cost[i]);
            if(min >= 0)
                return i;
        }
        return -1;
 }
}
  • 时间复杂度: O(n)O(n)O(n),其中 nnn 为数组 gasgasgas 的长度
  • 空间复杂度: O(1)O(1)O(1),仅用常数个额外变量

新手小白 如有问题 请多指教 求点赞

标签:站点,汽油,gas,问题,加油站,cost,diff,贪心
From: https://blog.csdn.net/2401_87659349/article/details/144385783

相关文章

  • PaddleClas棘手问题:ImportError: attempted relative import with no known parent pa
    PaddleClasImportError问题问题背景事先通过pipinstall-e.安装了editional版本的PaddleClas包,也在PYTHONPATH当中添加了相关路径,但是在执行模型推理时,还是遇到了这个问题:Traceback(mostrecentcalllast):File"/root/mambaforge/envs/py310/lib/python3.10/runpy.py......
  • 一个简单的整数问题(树状数组区间修改,单点查询)
    给定长度为 NN 的数列 AA,然后输入 MM 行操作指令。第一类指令形如 Clrd,表示把数列中第 l∼rl∼r 个数都加 dd。第二类指令形如 Qx,表示询问数列中第 xx 个数的值。对于每个询问,输出一个整数表示答案。输入格式第一行包含两个整数 NN 和 MM。第二行包含......
  • IDEA 2024.3 有效激活码,解决 We could not validate your license ff83b7bd51f5460ca4
    温馨提示:若激活失败或提示[keyisinvalid]的话需要完全卸载或尝试执行卸载脚本,然后重新安装即可解决;如果修改过host,请删除你添加的网址,如以前破解过,请完全卸载,重新安装;最新激活码激活失败,请重启重试。若提示Wecouldnotvalidateyourlicenseff83b7bd51f5460ca43aabd7a96......
  • 一种解决问题的方法
    今天,朋友说他的redmine服务器崩了。俺就想起了一段往事。很多很多年前,俺负责测试。当时公司自己开发了一个OnlineHelpDesk系统,用于保存测试到的bug、开放文档等。产品的每个版本发布,必须要bug清零后才可以发布。所以,产品要发布一定要经过俺准许。有一次,有个产品俺们测试出bug......
  • 我理解的跨域问题
    首先,跨域问题也算是计算机中的安全机制,是浏览器的安全机制。跨域问题是什么造成的浏览器的检查访问了不同域名的资源使用的xhr作为请求类型准确的讲,是因为上面的三个条件同时成立的时候,才会有跨域问题的存在如何解决跨域问题一般有以下几种思路:禁止浏览器的限制。这个......
  • unityGLTF插件加载模型很慢的问题
    在unity编辑器里面加载很快,但是发布成windows版本,加载就很慢排查原因是开启了多线程加载(编辑器环境多线程加载始终关闭反而更快):打开文件GLTFSceneImporter.cs///<summary>///UseMultithreadingornot.///Ineditor,thisisalwaysfalse.This......
  • # electron 打包 webview 嵌入需要调用电脑摄像头拍摄失败问题
    electron打包webview嵌入需要调用电脑摄像头拍摄失败问题这篇文章是接我cocos专栏的上一篇文章继续写的,我上一篇文章写的是cocos开发触摸屏项目,需要嵌入一个网页用来展示,最后通过electron打包成exe程序,而且网页里面是需要调用电脑摄像头进行拍摄的。问题通过前一篇......
  • 记录在中断向量上遇到的问题
    此篇文章在2023年3月28日被记录在中断向量上遇到的坑在工作中遇到一个坑,APP烧录在FLASH_BASE(0x08000000)地址,但是将APP烧录在指定地址(0x08006000)后正常程序可以运行,但是freertos无法启动调度器,在网上查阅资料后发现是中断向量的问题什么是中断向量中断向量表实际上就......
  • 违规抽烟识别智慧矿山一体机在矿山监控项目中,如何选择合适的POE网络摄像机以及常见问
    随着技术的飞速进步,POE(PoweroverEthernet,以太网供电)技术在安防监控领域的应用越来越广泛,它为网络监控施工带来了革命性的改变。POE技术允许通过单一的以太网电缆同时传输数据和电力,大大简化了监控系统的布线复杂度,并降低了安装成本。在矿山监控系统中,选择适合的POE技术可以提......
  • LiteGBS国标GB28181设备端接入SDK监控图像夜间显示图像存在黑白或彩色条纹问题,如何解
    监控图像出现黑白或彩色条纹的原因可能有多种,要解决这些问题,可以逐一排查,从检查摄像头的硬件和连接、重启设备、调整设置到更新软件等方面入手。摄像头故障:摄像头内部元件损坏,尤其是图像传感器或镜头,可能会导致图像出现条纹现象。信号干扰:电磁干扰或信号传输问题(例如,线路老化或......