【单调栈】LeetCode1776:车队

news2024/9/28 15:28:50

作者推荐

【贪心算法】【中位贪心】.执行操作使频率分数最大

涉及知识点

单调栈

题目

在一条单车道上有 n 辆车,它们朝着同样的方向行驶。给你一个长度为 n 的数组 cars ,其中 cars[i] = [positioni, speedi] ,它表示:
positioni 是第 i 辆车和道路起点之间的距离(单位:米)。题目保证 positioni < positioni+1 。
speedi 是第 i 辆车的初始速度(单位:米/秒)。
简单起见,所有车子可以视为在数轴上移动的点。当两辆车占据同一个位置时,我们称它们相遇了。一旦两辆车相遇,它们会合并成一个车队,这个车队里的车有着同样的位置和相同的速度,速度为这个车队里 最慢 一辆车的速度。
请你返回一个数组 answer ,其中 answer[i] 是第 i 辆车与下一辆车相遇的时间(单位:秒),如果这辆车不会与下一辆车相遇,则 answer[i] 为 -1 。答案精度误差需在 10^-5 以内。
示例 1:
输入:cars = [[1,2],[2,1],[4,3],[7,2]]
输出:[1.00000,-1.00000,3.00000,-1.00000]
解释:经过恰好 1 秒以后,第一辆车会与第二辆车相遇,并形成一个 1 m/s 的车队。经过恰好 3 秒以后,第三辆车会与第四辆车相遇,并形成一个 2 m/s 的车队。
示例 2:
输入:cars = [[3,4],[5,4],[6,3],[9,1]]
输出:[2.00000,1.00000,1.50000,-1.00000]
提示:
1 <= cars.length <= 105
1 <= position_{i} , speed_{i} <= 106
positioni < positioni+1

单调栈

车队的前后和数组的前后相反,按车队从前到后枚举i(i从大到小)。
有如下规律:
一,车队的第一辆车不会降速。所以相遇的时候只考虑车队头。
二,前面的车比当前车块,则不会被当前车追上。
三,一辆车在被追上前,追上前面的车。则不会成为车队头。
四,后面的车不能越过当前车,可以将二三的"当前车"扩大为"当前车及后面的车"。即情况二三的车被淘汰。
五,除栈顶的车外,都有可能成为车头,否则早被淘汰了。

规则二,使得前面速度快的车被淘汰,于是栈中的速度升序,形成单调栈

代码

核心代码

class Solution {
public:
	vector<double> getCollisionTimes(vector<vector<int>>& cars) {
		m_c = cars.size();
		vector<double> vRet(m_c, -1);
		stack<int> staIndex;
		for (int i = m_c - 1; i >= 0; i--)
		{
			while (staIndex.size() && (cars[staIndex.top()][1] >= cars[i][1]))
			{//淘汰速度快的车,当前车追不上。后面的车也追不上
				staIndex.pop();
			}
#define MeetTime (((double)cars[staIndex.top()][0] - cars[i][0]) / (cars[i][1] - cars[staIndex.top()][1]))
			auto MeetPre = [&]() {
				if (staIndex.empty() || (vRet[staIndex.top()] < 0))
				{
					return false;
				}
				return MeetTime >= vRet[staIndex.top()];
			};
			while (MeetPre())
			{//淘汰被追上前,就追上前面的车
				staIndex.pop();
			}
			if (staIndex.size())
			{
				vRet[i] = MeetTime;
			}
			staIndex.emplace(i);
		}
		return vRet;
	}
	int m_c;
};

测试用例

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()
{
	vector<vector<int>> cars;
	{
		Solution slu;
		cars = { {1,2},{2,1},{4,3},{7,2} };
		auto res = slu.getCollisionTimes(cars);
		Assert({ 1.00000,-1.00000,3.00000,-1.00000 }, res);
	}
	{
		Solution slu;
		cars = { {3,4},{5,4},{6,3},{9,1} };
		auto res = slu.getCollisionTimes(cars);
		Assert({ 2.00000,1.00000,1.50000,-1.00000 }, res);
	}
	
	
	//CConsole::Out(res);
}

2023年3月版

class Solution {
public:
vector getCollisionTimes(vector<vector>& cars) {
m_c = cars.size();
vector vRet(m_c, -1);
std::stack sta;//碰撞时,可能的出头
sta.push(m_c - 1);
for (int i = m_c - 1 - 1; i >= 0; i–)
{
while (sta.size())
{
const int iPre = sta.top();
if (cars[i][1] <= cars[iPre][1])
{//速度慢或相等,永远无法撞上
sta.pop();
}
else
{
const double dMeetTime = (double)(cars[iPre][0] - cars[i][0]) / (cars[i][1] - cars[iPre][1]);
if ((vRet[sta.top()] > 0 ) && (dMeetTime >= vRet[iPre]))
{
sta.pop();
}
else
{
break;
}
}
}
if (sta.size())
{
const int iPre = sta.top();
const double dMeetTime = (double)(cars[iPre][0] - cars[i][0]) / (cars[i][1] - cars[iPre][1]);
vRet[i] = dMeetTime;
}
else
{
vRet[i] = -1;
}
sta.push(i);
}
return vRet;
}
int m_c;
};

2023年7月版

class Solution {
public:
vector getCollisionTimes(vector<vector>& cars) {
m_c = cars.size();
std::stack sta;
sta.emplace(m_c - 1);
vector vRet(m_c, -1);
for (int i = m_c - 2; i >= 0; i–)
{
//确保栈顶元素是相撞的车,两个条件:一,此车不能快于当前车 二,此车不能被撞之前撞上其它车
#define CurCar cars[i]
#define PreCar cars[sta.top()]
#define MeetTime ((double)PreCar[0] - CurCar[0])/(CurCar[1] - PreCar[1])
#define NeedMove1 (CurCar[1] <= PreCar[1])
#define NeedMove2 (vRet[sta.top()] > 1e-9) && ( MeetTime > vRet[sta.top()])
while (sta.size() && (NeedMove1 || NeedMove2))
{
sta.pop();
}
vRet[i] = sta.size() ? MeetTime : -1;
sta.push(i);
}
return vRet;
}
int m_c;
};

2023年9月版

class Solution {
public:
vector getCollisionTimes(vector<vector>& cars) {
m_c = cars.size();
vector vRet(m_c,-1);
std::stack sta;
for (int i = m_c - 1; i >= 0; i–)
{
while (sta.size())
{
int pre = sta.top();
if (cars[i][1] - cars[pre][1] <= 0)
{
sta.pop();
}
else
{
double dMeet = (cars[pre][0] - cars[i][0]) / (double)(cars[i][1] - cars[pre][1]);
if ((abs(vRet[pre] + 1) < 0.0001) || (dMeet < vRet[pre]))
{
vRet[i] = dMeet;
break;
}
else
{
sta.pop();
}
}
}
sta.emplace(i);
}
return vRet;
}
int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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.coloradmin.cn/o/1323423.html

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

相关文章

markdown文档主题颜色修改

目录 1、选择任意想选择的markdown文档主题css文件&#xff1a; 2、修改背景颜色 1、选择任意想选择的markdown文档主题css文件&#xff1a; 使用工具Typora文件主题路径&#xff1a; C:\Users\AppData\Roaming\Typora\themes&#xff0c;此处我这边就是copy了xydark的css文…

【LeetCode刷题笔记(8-2)】【Python】【接雨水】【单调栈】【困难】

文章目录 引言接雨水题目描述提示 解决方案2&#xff1a;【单调栈】结束语 【接雨水】 【LeetCode刷题笔记&#xff08;8-1&#xff09;】【Python】【接雨水】【动态规划】【困难】 引言 编写通过所有测试案例的代码并不简单&#xff0c;通常需要深思熟虑和理性分析。虽然这…

总线地址/物理地址/虚拟地址

参考&#xff1a; 总线地址、物理地址、虚拟地址-CSDN博客 内存管理&#xff1a;物理地址、虚拟地址、逻辑地址_虚拟地址和物理地址-CSDN博客 总线地址 总线地址和地址总线是一个概念。地址总线 (Address Bus&#xff1b;又称&#xff1a;位址总线) 属于一种电脑总线 &#xf…

React和umi搭建项目的操作步骤

​​​​​​一、react脚手架新建项目 (1.1)、命令行 前提&#xff1a;react ES2015,nodejs v8 npx create-react-app myReactName //2022年v16以下版本 myReactName(自定义项目名) react中文官网&#xff0c;快速上手&#xff1a;react中文官网 react框架&#xff0c;…

Linux系统中查看路由表的命令(ip route)

以下命令是在Linux系统中查看路由表的命令&#xff1a; 在Linux系统中&#xff0c;有多种方法可以查看路由设置。以下是一些常用的命令&#xff1a; ip route 或 ip -4 route&#xff08;IPv4&#xff09;/ ip -6 route&#xff08;IPv6&#xff09;&#xff1a; 这是最常用且功…

算法设计与分析期末知识点总结

一、概论 1、算法设计的目标&#xff1a; &#xff08;1&#xff09;正确性 &#xff08;2&#xff09;可使用性&#xff08;用户友好性&#xff09; &#xff08;3&#xff09;可读性 &#xff08;4&#xff09;健壮性 &#xff08;5&#xff09;高效率与低存储量需求 算…

vue 快速入门+vite前端构建工具

四、Vue3简介和快速体验 4.1 Vue3介绍 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简…

迪文屏开发保姆级教程——页面键盘

迪文屏页面键盘保姆级教程。 本篇文章主要介绍了在DGBUS平台上使用页面键盘的步骤。 文章目录 一、前言 开发环境 二、使用步骤 1.准备素材 2.打开DGUS工程&#xff0c;导入素材。 3.生成ICL文件。 4.添加数据变量显示控件 5.添加数据录入控件 A.变量地址设置 B.变量类…

外媒发稿最好的宣传方法是什么?大舍传媒

外媒发稿最好的宣传方法是什么&#xff1f; 引言 在如今信息爆炸的时代&#xff0c;外媒发稿的宣传方法至关重要。大舍传媒作为一家业内知名的传媒公司&#xff0c;积累了丰富的经验和成功案例。本文将探讨外媒发稿最好的宣传方法&#xff0c;旨在帮助读者更好地推广自己的信…

将输入的文本包装成多个行使每行的字符数不超过指定的列宽textwrap.fill()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将输入的文本包装成多个行 使每行的字符数不超过指定的列宽 textwrap.fill() [太阳]选择题 请问以下代码每行最多能输出字符数是&#xff1f; import textwrap text "This is a long …

(PC+WAP)装修设计公司网站模板 家装公司网站源码下载

(PCWAP)装修设计公司网站模板 家装公司网站源码下载 PbootCMS内核开发的网站模板&#xff0c;该模板适用于装修设计、家装公司类等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b; PCWAP&#xff0c;同一个后台&#xff0c…

【Redis】四、Redis.conf详解

文章目录 Redis.conf详解单位网络通用 GENERAL快照REPLICATION 复制SECURITY 安全限制 CLIENTSAPPEND ONLY 模式 aof配置 Redis.conf详解 启动的时候&#xff0c;就通过配置文件来启动&#xff01; 工作中&#xff0c;一些小小的配置&#xff0c;可以让你脱颖而出&#xff01;…

多域名证书和通配符证书的区别?

先来说说多域名证书&#xff08;别急&#xff0c;通配符证书&#xff0c;马上就有戏&#xff09;。多域名证书&#xff0c;正式的名字叫主题备用名称&#xff08;SAN&#xff09;证书。想象一下&#xff0c;它们就像是一个超级英雄联盟&#xff0c;能在一个SSl证书下保护包含不…

《Linux C编程实战》笔记:进程操作之退出,执行,等待

进程退出 进程退出表示进程即将运行结束。在Linux中退出分为正常退出和异常退出。 正常退出&#xff1a; 在main函数中执行return调用exit函数调用_exit函数 异常退出&#xff1a; 调用abort函数收到某个信号&#xff0c;这个信号是程序终止 退出方式比较 exit和return的…

「Verilog学习笔记」游戏机计费程序

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1nsmodule game_count(input rst_n, //异位复位信号&#xff0c;低电平有效input clk, //时钟信号input [9:0]money,input set,input boost,output reg[9:0…

工业缺陷检测新时代!OpenCV4六种方法助你轻松应对生产难题!

OpenCV4工业缺陷检测的六种方法 机器视觉缺陷检测好书推荐工业上常见缺陷检测方法方法一&#xff1a;方法二&#xff1a;方法三&#xff1a;方法四&#xff1a;方法五&#xff1a;方法六&#xff1a; 写在末尾&#xff1a; 主页传送门&#xff1a;&#x1f4c0; 传送 送书系列…

Module build failed: TypeError: this.getOptions is not a function

在使用webpack打包出现以上错误时&#xff0c;可能是你安装的css-loader和style-loader的版本过高。 我用的webpack版本是3.6.0 因此需要降低一下版本 在你编辑器终端输入以下命令&#xff1a; npm install css-loader3.6.0 npm install --save-dev style-loader1.00 然后接下…

八大易犯领英LinkedIn错误

领英是一个全球知名的职场社交平台&#xff0c;拥有海量的用户&#xff0c;也成为了外贸人开发客户的一个重要平台。但是如果没有很好地避好一些易犯错误&#xff0c;那很可能努力的结果是事倍功半。接下来我来讲解八大容易犯的领英错误。 1、没有完善个人信息 领英是一个职场…

基于单片机的智能小车 (论文+源码)

1. 系统设计 此次可编程智能小车系统的设计系统&#xff0c;结合STM32单片机&#xff0c;蓝牙模块&#xff0c;循迹模块&#xff0c;电机驱动模块来共同完成本次设计&#xff0c;实现小车的循迹避障功能和手机遥控功能&#xff0c;其整体框架如图2.1所示。其中&#xff0c;采用…

淘宝类目信息API接口获取淘宝商品分类信息API调用说明(含APIkey密钥)

cat_get-获得淘宝分类详情 item_cat_get-获得淘宝商品类目 公共参数 名称类型必须描述keyString是调用key&#xff08;点此获取&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_…