【大根堆】【C++算法】871 最低加油次数

作者推荐

【动态规划】【map】【C++算法】1289. 下降路径最小和 II

本文涉及知识点

大根堆 优先队列

LeetCode:871最低加油次数

汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。
沿途有加油站,用数组 stations 表示。其中 stations[i] = [positioni, fueli] 表示第 i 个加油站位于出发位置东面 positioni 英里处,并且有 fueli 升汽油。
假设汽车油箱的容量是无限的,其中最初有 startFuel 升燃料。它每行驶 1 英里就会用掉 1 升汽油。当汽车到达加油站时,它可能停下来加油,将所有汽油从加油站转移到汽车中。
为了到达目的地,汽车所必要的最低加油次数是多少?如果无法到达目的地,则返回 -1 。
注意:如果汽车到达加油站时剩余燃料为 0,它仍然可以在那里加油。如果汽车到达目的地时剩余燃料为 0,仍然认为它已经到达目的地。
示例 1:
输入:target = 1, startFuel = 1, stations = []
输出:0
解释:可以在不加油的情况下到达目的地。
示例 2:
输入:target = 100, startFuel = 1, stations = [[10,100]]
输出:-1
解释:无法抵达目的地,甚至无法到达第一个加油站。
示例 3:
输入:target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]
输出:2
解释:
出发时有 10 升燃料。
开车来到距起点 10 英里处的加油站,消耗 10 升燃料。将汽油从 0 升加到 60 升。
然后,从 10 英里处的加油站开到 60 英里处的加油站(消耗 50 升燃料),
并将汽油从 10 升加到 50 升。然后开车抵达目的地。
沿途在两个加油站停靠,所以返回 2 。
参数:
1 <= target, startFuel <= 109
0 <= stations.length <= 500
1 <= positioni < positioni+1 < target
1 <= fueli < 109

分析

加油站的位置已经按升序排序。
iCan 记录加油i次后,能到达的最远位置。i 取值区间[0,stations.length]
第i+1次加油,一定是iPreCan(第i次加油的iCan)能到达且没有加油,油量最大的加油站。
如果没有到达终点,且无油可加返回-1。

代码

核心代码

class Solution {
public:int minRefuelStops(int target, int startFuel, vector<vector<int>>& stations) {int iCan = startFuel;priority_queue<int> canAdd;int j = 0;for (int i = 0; i < stations.size(); i++){if (iCan >= target){return i;}//canAdd能加油的加油站while ((j < stations.size()) && (stations[j][0] <= iCan)){canAdd.emplace(stations[j++][1]);}if (canAdd.empty()){return -1;}iCan += canAdd.top();canAdd.pop();}return (iCan >= target) ? stations.size() : -1;}
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{	int target,  startFuel;vector<vector<int>> stations;{Solution sln;target = 1, startFuel = 1, stations = {};auto res = sln.minRefuelStops(target, startFuel, stations);Assert(res, 0);}{Solution sln;target = 100, startFuel = 1, stations = { {10,100} } ;auto res = sln.minRefuelStops(target, startFuel, stations);Assert(res, -1);}{Solution sln;target = 100, startFuel = 10, stations = { {10, 60},{20, 30},{30, 30},{60, 40} };auto res = sln.minRefuelStops(target, startFuel, stations);Assert(res, 2);}	{Solution sln;target = 100, startFuel = 50, stations = { {25, 25},{50, 50} };auto res = sln.minRefuelStops(target, startFuel, stations);Assert(res, 1);}}

2023年1月第一版

class Solution {
public:
int minRefuelStops(int target, int startFuel, vector<vector>& stations) {
std::unordered_map<int,int> preDp;
preDp[0] = startFuel;
int iPrePos = 0;
for (auto& v : stations)
{
std::unordered_map<int, int> dp;
for (auto& pre : preDp)
{
const int iHasFuel = pre.second - (v[0] - iPrePos);
if (iHasFuel < 0 )
{
continue;
}
Add(dp, pre.first, iHasFuel);
Add(dp, pre.first+1, iHasFuel + v[1]);
}
preDp.swap(dp);
iPrePos = v[0];
}
int iMinNum = INT_MAX;
for (auto& pre : preDp)
{
const int iHasFuel = pre.second - (target - iPrePos);
if (iHasFuel < 0)
{
continue;
}
iMinNum = min(iMinNum, pre.first);
}
return (INT_MAX == iMinNum) ? -1 : iMinNum;
}
void Add(std::unordered_map<int, int>& dp, int iNum, int iFuel)
{
iFuel = min(iFuel, 1000 * 1000 * 1000);
auto it = dp.find(iNum);
if (dp.end() == it)
{
dp[iNum] = iFuel;
}
else
{
it->second = max(it->second, iFuel);
}
}
};

2023年1月 第二版

class Solution {
public:
int minRefuelStops(int target, int startFuel, vector<vector>& stations) {
m_iFuel = startFuel;
for (auto& v : stations)
{
Add(v[0]);
if (m_iFuel < v[0])
{
return -1;
}
m_qFuel.push(v[1]);
}
Add(target);
if (m_iFuel < target)
{
return -1;
}
return stations.size() - m_qFuel.size();
}
void Add(int iNeedFuel)
{
while (m_qFuel.size() && (m_iFuel < iNeedFuel))
{
m_iFuel += m_qFuel.top();
m_qFuel.pop();
}
}
std::priority_queue m_qFuel;
int m_iFuel;
};

2023年 8月版

class Solution {
public:
int minRefuelStops(int target, int startFuel, vector<vector>& stations) {
stations.emplace_back(vector{target, 0});
int iRet = 0;
std::multiset setCanAdd;
int iHas = startFuel;
for (const auto& v : stations)
{
while (setCanAdd.size() && (iHas < v[0]))
{//油不够,需要加油
iHas += *setCanAdd.rbegin();
setCanAdd.erase(std::prev(setCanAdd.end()));
iRet++;
}
if (iHas < v[0])
{
return -1;
}
setCanAdd.emplace(v[1]);
}
return iRet;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/649019.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用4KB内存寻找重复元素(算法村第十五关青铜挑战)

在海量数据中&#xff0c;普通的数组、链表、Hash、树等等结构无效&#xff0c;因为内存空间不足。而常规的递归、排序&#xff0c;回溯、贪心和动态规划等思想也无效&#xff0c;因为执行超时。这类问题该如何下手呢&#xff1f;这里介绍三种非常典型的思路&#xff1a; 1.使…

如何在Vue项目中应用TypeScript?

文章目录 一、前言二、使用Componentcomputed、data、methodspropswatchemit 三 、总结 一、前言 与link类似 在VUE项目中应用typescript&#xff0c;我们需要引入一个库vue-property-decorator&#xff0c; 其是基于vue-class-component库而来&#xff0c;这个库vue官方推出…

Caused by: com.mongodb.MongoTimeoutException: Timed out after 30000 ms

报错 Caused by: com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting to connect. Client view of cluster state is {typeUNKNOWN, servers[{addressmangodb-m.cc.com:3717, typeUNKNOWN, stateCONNECTING, exception{com.mongodb.MongoSocketReadE…

uniapp 使用echarts做折线图条形图。

提前10天把中烟活动做完了&#xff0c;以为能打酱油到除夕那天&#xff0c;结果又要做什么数据看板&#xff0c;方便烟草领导过年查看数据&#xff0c;还只给5天时间&#xff0c;真实压榨剥削啊&#xff0c;下辈子再也不‘拍黄片’了&#xff0c;不&#xff01;下份工作我就转前…

操作系统--Linux虚拟内存管理

​一、什么是虚拟内存地址 收货地址是一个虚拟地址&#xff0c;它是人为定义的 而我们的城市&#xff0c;小区&#xff0c;街道是真实存在的&#xff0c;他们的地理位置就是物理地址 以 Intel Core i7 处理器为例&#xff0c;64 位和32位虚拟地址的格式为&#xff1a; 二、为什…

Android App开发基础(3)——App的设计规范

3 App的设计规范 本节介绍了App工程的源码设计规范&#xff0c;首先App将看得见的界面设计与看不见的代码逻辑区分开&#xff0c;然后利用XML标记描绘应用界面&#xff0c;同时使用Java代码书写程序逻辑&#xff0c;从而形成App前后端分离的设计规约&#xff0c;有利于提高App集…

Fastbee开源物联网项目RoadMap

架构优化 代码简化业务&协议解耦关键组件支持横向拓展网络协议支持横向拓展&#xff0c;包括&#xff1a;mqtt broker,tcp,coap,udp,sip等协议插件化编码脚本化业务代码模版化消息总线 功能优化 网关/子网关&#xff1a;上线&#xff0c;绑定&#xff0c;拓扑&#xff0…

快毕业了,同学纪念册如何制作出高级感

​快毕业了&#xff0c;这是一个充满回忆和感慨的时刻。同学们都想制作一本高级感的同学纪念册&#xff0c;留住这段美好的时光。但是自己着手制作的纪念册太丑&#xff0c;那不出手怎么办&#xff1f;那你就问对人了&#xff0c;我给大家演示几个步骤&#xff0c;需要的可以学…

【java】常见的面试问题

目录 一、异常 1、 throw 和 throws 的区别&#xff1f; 2、 final、finally、finalize 有什么区别&#xff1f; 3、try-catch-finally 中哪个部分可以省略&#xff1f; 4、try-catch-finally 中&#xff0c;如果 catch 中 return 了&#xff0c;finally 还会执行吗&#…

ambari hdp 企业级安装实战

一 配置部署环境 1.1 检查操作系统 1.1.1 检查操作系统版本 cat /etc/redhat-release1.1.2 检查操作系统默认语言 $ echo $LANG en_US.UTF-8若操作系统默认语言为en_US.UTF-8,则进入下一步。 若操作系统默认语言非en_US.UTF-8,则执行以下步骤: # 将默认语言由中文切换为…

瀑布流布局 (初版)

瀑布流布局 文章目录 瀑布流布局前言1. 背景2. 点⬇️&#x1f517;去体验效果如下图所示&#xff1a; 一、初版waterfall布局和问题暴露&#xff1f;1.效果图如下&#xff1a;2.暴露问题如下图所示&#xff1a;第一张问题图&#xff1a;第二张问题图&#xff1a; 3.HTML代码如…

有效的字母异位词

42. 有效的字母异位词https://leetcode.cn/problems/valid-anagram/ 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 示例 1: 输入: s …

go语言Map与结构体

1. Map map是一种无序的基于key-value的数据结构&#xff0c;Go语言中的map是引用类型&#xff0c;必须初始化才能使用。 1.1. map定义 Go语言中 map的定义语法如下 map[KeyType]ValueType其中&#xff0c; KeyType:表示键的类型。ValueType:表示键对应的值的类型。map类型的…

maven组件升级报错经验汇总

1. NosuchMethodError org.springframework.beans.factory.support.genericBeanDefinition(xxxxx) 2. ClassNotFoundException: org.springframework.boot.SpringApplication 可能冲突的依赖是&#xff1a; <dependency><groupId>org.springframework.boot</g…

NodeJS Express实现所有页面Http访问重定向跳转为Https

要在Node.js Express中实现所有页面从HTTP访问跳转到HTTPS&#xff0c;你可以使用重定向中间件。以下是一个简单的示例&#xff1a; 1. 首先&#xff0c;确保你已经安装了Express和express-redirect中间件。如果没有&#xff0c;你可以通过npm进行安装&#xff1a; npm insta…

8.6 代理设计模式

文章目录 一、代理模式&#xff08;Proxy Pattern&#xff09;概述二、代理模式和观察者设计模式三、模式结构四、协作角色五、实现策略六、相关模式七、示例八、应用 一、代理模式&#xff08;Proxy Pattern&#xff09;概述 代理模式是一种设计模式&#xff0c;它通过引入一个…

智能体AI Agent的极速入门:从ReAct到AutoGPT、QwenAgent、XAgent

前言 如这两天在微博上所说&#xff0c;除了已经在七月官网上线的AIGC模特生成系统外&#xff0c;我正在并行带多个项目组 第二项目组&#xff0c;论文审稿GPT第2版的效果已经超过了GPT4&#xff0c;详见《七月论文审稿GPT第2版&#xff1a;用一万多条paper-review数据集微调…

跨语言编程:在C#应用程序中调用Python

应用场景 众所周知&#xff0c;Python在深度学习中占有绝对优势。而C#语言的优势在各种后端应用开发&#xff0c;特别是工业领域。当我们使用 C# 开发应用程序时&#xff0c;可能需要调用 Python 代码来实现某些功能。这时&#xff0c;我们可以使用 Python.NET 或 IronPython 等…

69.x 的平方根(力扣LeetCode)

69.x 的平方根&#xff08;力扣LeetCode&#xff09; 题目描述 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a;不允许使用任何内置指数函数和算符&…

Vue-38、Vue中插件使用

1、新建plugins.js文件 2、可以在plugins.js 定义全局过滤器 定义全局指令 定义混入 给vue原型上添加一个方法 export default {install(Vue){console.log("install",Vue);//全局过滤器Vue.filter(mySlice,function (value) {return value.slice(0,4)});//定义全局…