[二分查找]LeetCode1964:找出到每个位置为止最长的有效障碍赛跑路线

news2024/11/18 3:44:08

本文涉及的基础知识点

二分查找算法合集

作者推荐

动态规划LeetCode2552:优化了6版的1324模式

题目

你打算构建一些障碍赛跑路线。给你一个 下标从 0 开始 的整数数组 obstacles ,数组长度为 n ,其中 obstacles[i] 表示第 i 个障碍的高度。
对于每个介于 0 和 n - 1 之间(包含 0 和 n - 1)的下标 i ,在满足下述条件的前提下,请你找出 obstacles 能构成的最长障碍路线的长度:
你可以选择下标介于 0 到 i 之间(包含 0 和 i)的任意个障碍。
在这条路线中,必须包含第 i 个障碍。
你必须按障碍在 obstacles 中的 出现顺序 布置这些障碍。
除第一个障碍外,路线中每个障碍的高度都必须和前一个障碍 相同 或者 更高 。
返回长度为 n 的答案数组 ans ,其中 ans[i] 是上面所述的下标 i 对应的最长障碍赛跑路线的长度。
示例 1:
输入:obstacles = [1,2,3,2]
输出:[1,2,3,3]
解释:每个位置的最长有效障碍路线是:

  • i = 0: [1], [1] 长度为 1
  • i = 1: [1,2], [1,2] 长度为 2
  • i = 2: [1,2,3], [1,2,3] 长度为 3
  • i = 3: [1,2,3,2], [1,2,2] 长度为 3
    示例 2:
    输入:obstacles = [2,2,1]
    输出:[1,2,1]
    解释:每个位置的最长有效障碍路线是:
  • i = 0: [2], [2] 长度为 1
  • i = 1: [2,2], [2,2] 长度为 2
  • i = 2: [2,2,1], [1] 长度为 1
    示例 3:
    输入:obstacles = [3,1,5,6,4,2]
    输出:[1,1,2,3,2,2]
    解释:每个位置的最长有效障碍路线是:
  • i = 0: [3], [3] 长度为 1
  • i = 1: [3,1], [1] 长度为 1
  • i = 2: [3,1,5], [3,5] 长度为 2, [1,5] 也是有效的障碍赛跑路线
  • i = 3: [3,1,5,6], [3,5,6] 长度为 3, [1,5,6] 也是有效的障碍赛跑路线
  • i = 4: [3,1,5,6,4], [3,4] 长度为 2, [1,4] 也是有效的障碍赛跑路线
  • i = 5: [3,1,5,6,4,2], [1,2] 长度为 2
    参数范围
    n == obstacles.length
    1 <= n <= 105
    1 <= obstacles[i] <= 107

分析:二分有序映射

时间复杂度

O(nlogn),枚举终点O(n),每个终点二分查找O(logn)。

变量解析

mHeightNum,键是路障搞定,值是以当前路障为终点的最长路障路线。

代码

template<class _Kty,class _Ty,bool bValueDdes,bool bOutSmallKey>
class COrderValueMap
{
public:
void Add (_Kty key, _Ty value)
{
if (bOutSmallKey)
{
if (bValueDdes)
{
AddOutSmall(key, value, std::less_equal<_Ty>(), std::greater_equal<_Ty>());
}
else
{
assert(false);
}
}
else
{
if (bValueDdes)
{
AddNotOutSmall(key, value, std::greater_equal<_Ty>(), std::less_equal<_Ty>());
}
else
{
AddNotOutSmall(key, value, std::less_equal<_Ty>(), std::greater_equal<_Ty>());
}
}
};
std::map<_Kty, _Ty> m_map;
protected:
template<class _Pr1, class _Pr2>
void AddOutSmall(_Kty key, _Ty value, _Pr1 pr1, _Pr2 pr2)
{
auto it = m_map.lower_bound(key);
if ((m_map.end() != it) && pr1(it->second, value))
{
return;//被旧值淘汰
}
auto ij = it;
while (it != m_map.begin())
{
–it;
if (pr2(it->second, value))
{
it = m_map.erase(it);
}
}
m_map[key] = value;
}
template<class _Pr1, class _Pr2>
void AddNotOutSmall(_Kty key, _Ty value, _Pr1 pr1,_Pr2 pr2 )
{
auto it = m_map.upper_bound(key);
if ((m_map.begin() != it) && pr1(std::prev(it)->second, value))
{
return;//被淘汰
}
auto ij = it;
for (; (m_map.end() != ij) && pr2(ij->second, value); ++ij);
m_map.erase(it, ij);
m_map[key] = value;
};

};

class Solution {
public:
vector longestObstacleCourseAtEachPosition(vector& obstacles) {
COrderValueMap<int, int, true, false> mHeightNum;
vector vRet;
for (const auto& n : obstacles)
{
auto it = mHeightNum.m_map.upper_bound(n);
const int iCurNum = (mHeightNum.m_map.begin() == it) ? 1 : (1 + std::prev(it)->second);
vRet.emplace_back(iCurNum);
mHeightNum.Add(n, iCurNum);
}
return vRet;
}
};

二分有序向量

vLenToMin[i]表示长度为i的路障,终点路障高度为:vLenToMin[i]。如果有相同的路障长度,终点路障高度取最小值。

代码

 class Solution {
   public:
	   vector<int> longestObstacleCourseAtEachPosition(vector<int>& obstacles) {
		   vector<int> vLenToMin = { 0 };
		   vector<int> vRet;
		   for (const auto& n : obstacles)
		   {
			   int index = std::upper_bound(vLenToMin.begin(), vLenToMin.end(),n) - vLenToMin.begin();
			   if (index >= vLenToMin.size())
			   {
				   vLenToMin.emplace_back(n);
			   }
			   else
			   {
				   vLenToMin[index] = min(vLenToMin[index], n);
			   }
			   vRet.emplace_back(index);
		   }
		   return vRet;
	   }
   };

2023年3月版旧代码

class Solution {
public:
vector longestObstacleCourseAtEachPosition(vector& obstacles) {
std::map<int, int> mHeightNum;
vector vRet;
for (const auto& obs : obstacles)
{
auto it = mHeightNum.upper_bound(obs);
int iNum = 1;
if (mHeightNum.begin() != it)
{
auto tmp = it;
iNum = (–tmp)->second+1;
}
if (mHeightNum.end() != it)
{
if (iNum >= it->second)
{
mHeightNum.erase(it);
}
}
mHeightNum[obs] = iNum;
vRet.push_back(iNum);
}
return vRet;
}
};

2023年7月旧代码

class Solution {
public:
vector longestObstacleCourseAtEachPosition(vector& obstacles) {
std::vector vHeight(obstacles.begin(), obstacles.end());
sort(vHeight.begin(), vHeight.end());
vHeight.erase(std::unique(vHeight.begin(), vHeight.end()), vHeight.end());
std::unordered_map<int, int> mValueToIndex;
for (int i = 0; i < vHeight.size(); i++)
{
mValueToIndex[vHeight[i]] = i;
}
CMaxLineTree tree(mValueToIndex.size());
vector vRet;
for (const auto& n : obstacles)
{
const int index = mValueToIndex[n];
const auto iRet = tree.Query(0, index) + 1;
vRet.emplace_back(iRet);
tree.Modify(index, iRet);
}
return vRet;
}
};

扩展阅读

视频课程

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

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

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

相关文章

nvidia安装出现7-zip crc error解决办法

解决办法&#xff1a;下载network版本&#xff0c;重新安装。&#xff08;选择自己需要的版本&#xff09; 网址&#xff1a;CUDA Toolkit 12.3 Update 1 Downloads | NVIDIA Developer 分析原因&#xff1a;local版本的安装包可能在下载过程中出现损坏。 本人尝试过全网说的…

PT读spef报PARA-006如何解决?

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 There are multiple causes that can trigger PARA-006 errors. Here is a checklist. 1) SPEF reading order Functionally, the parasitic files can be read in any order. For best stitching…

许战海战略文库|重回大众视野的健力宝如何重生

摘要&#xff1a;销售额连续7年没有增长;产业主品牌定位不清晰;产品不协同缺少产品战略;子品牌无法形成合力新产品共性不足;过度差异化缺少渠道战略;被渠道能力更强的品牌挤压。火遍世界的“东方魔水”从第一品牌到被人遗忘&#xff0c;健力宝该如何重生? 健力宝诞生于1984年&…

Flutter学习(七)GetX offAllNamed使用的问题

背景 使用GetX开发应用的时候&#xff0c;也可能有人调用过offAllNamed&#xff0c;会发现所有controller的都被销毁了 环境 win10 getx 4.6.5 as 4 现象 从A页面&#xff0c;跳转到B页面&#xff0c;然后调用offAllNamed进行回到A页面&#xff0c;观察controller声明周期…

企业如何进行数据资产化?

首先我们要了解什么是数据资产 关于数据资产的定义&#xff0c;最开始是有一些的。比如在国民经济核算领域&#xff0c;认为资产是根据所有权原则界定的经济资产&#xff0c;即资产必须为某个或某些经济单位所拥有&#xff0c;其所有者因持有或使用它们而获得经济利益。更多强调…

WordPress采集器自动采集发布的工具

WordPress作为最受欢迎的内容管理系统之一&#xff0c;其强大的功能和灵活性使其成为许多网站、博客和电子商务平台的首选。WordPress采集器自动采集发布内置采集规则是一项备受关注的功能&#xff0c;让用户可以轻松收集并发布内容。WordPress采集器自动采集发布内置采集规则的…

3.3 路由器的远程配置

实验3.3 路由器的远程配置 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施&#xff08;一&#xff09;、配置通过Telnet登录系统1.RA的基本配置2.RB的基本配置3.在RA上配置Telnet用户登录界面 &#xff08;二&#xff09;、配置通过STelnet登录系统1.RA的基本配…

让SaaS盈利的两个驱动力

内容来自演讲&#xff1a;张星亮 | 六度人和&#xff08;EC&#xff09;| 创始人兼CEO 摘要 文章主要介绍了 SaaS 行业的发展趋势和盈利的两个驱动力&#xff1a;分工和AI。 首先&#xff0c;分工是提高效率和降低成本的关键。文章提到了 SaaS 行业正在从一体化向组合型销售…

用通俗的方法讲解:大模型微调训练详细说明(附理论+实践代码)

本文内容如下 介绍了大模型训练的微调方法&#xff0c;包括prompt tuning、prefix tuning、LoRA、p-tuning和AdaLoRA等。 介绍了使用deepspeed和LoRA进行大模型训练的相关代码。 给出了petals的介绍&#xff0c;它可以将模型划分为多个块&#xff0c;每个用户的机器负责其中一…

基于SpringBoot校园周边美食探索及分享平台的设计与实现

摘要&#xff1a; 美食一直是与人们日常生活息息相关的产业。传统的电话订餐或者到店消费已经不能适应市场发展的需求。随着网络的迅速崛起&#xff0c;互联网日益成为提供信息的最佳俱渠道和逐步走向传统的流通领域&#xff0c;传统的美食业进而也面临着巨大的挑战&#xff0c…

Todesk 无法登录,无法联网

前言 我习惯用todesk远程ubuntu&#xff0c;但是突然发现掉线了&#xff0c;但是ssh还能连接 问题查找 1.ping 一下主机ip 2.ssh连接后&#xff0c;ping 一下百度&#xff0c;查看是否外网正常 3.输入一下命令 ps -ef | grep todesk #查看todesk 进程 sudo kill -9 ....…

红队攻防实战之某商城Getshell

此后如竟没有炬火&#xff0c;我便是唯一的光 信息收集 端口扫描 nmap -T4 -A -p 1-65535 可以看到目标系统开放22、80、888、3306、8800端口 敏感文件扫描 http:///admin/login.html 后台登陆地址泄露 漏洞挖掘 phpinfo信息泄露 phpinfo信息泄露&#xff0c;此站为Linu…

Linux环境下ARM开发

目录 前言ARM启动及开发基础1.Cortex-A架构2.启动方式3.汇编基础4.Makefile语法基础5.Makefile补充6.编译下载 结语 前言 主要介绍基于linux开发环境下&#xff0c;如何开发ARM A7 ARM启动及开发基础 1.Cortex-A架构 1&#xff09;Cortex-A7运行模式 模式说明User(USR)用户模…

element中el-input限制只输入正整数或保留两位小数

文章目录 一、前言二、实现2.1、HTML2.2、只输入正整数2.3、只能输入数字或小数点 三、最后 一、前言 常见的el-input可能会限制用户只能输入正整数或保留两位小数&#xff0c;达到输入金额的需求&#xff0c;点击【跳转】访问el-input的官方文档 element-ui是有el-input-numb…

Git的介绍和下载安装

Git的介绍和下载安装 概述 Git是一个分布式版本控制工具, 通常用来管理项目中的源代码文件(Java类、xml文件、html页面等)进行管理,在软件开发过程中被广泛使用 Git可以记录文件修改的历史记录并形成备份从而实现代码回溯, 版本切换, 多人协作, 远程备份的功能Git具有廉价的…

VSC++=》 拆解整数对号入座重组

void 拆解整数对号入座重组(int& 数, bool 选 true) {int 对号[10]{}, j 选 ? 9 : 0, 反 0, 基 1;while (数)对号[数 % 10], 数 / 10;if (选)while (j > 0)if (对号[j])数 * 10, 数 j, (反 ? 基 * 10 : 0), 反 基 * j, --对号[j]; else --j;else while (j < …

UI自动化Selenium find_elements和find_element的区别

# 如果获取的element是list&#xff0c;那么需要用find_elements方法&#xff1b;此方法会返回list&#xff0c;然后使用len() 方法&#xff0c;计算对象的个数&#xff1b; # find_element方法返回的不是list对象&#xff0c;所以导致没办法计算对象个数 # 1.返回值类型不同…

go开发之个人微信号机器人开发

简要描述&#xff1a; 下载消息中的文件 请求URL&#xff1a; http://域名地址/getMsgFile 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型…

okhttp导致的内存溢出(OOM)sun.security.ssl.SSLSocketImpl

使用分析工具&#xff1a;MAT(Memory Analyzer Tool)、JvisualVM占用内存&#xff1a;sun.security.ssl.SSLSocketImpl 一、 项目场景&#xff1a; 功能&#xff1a;一个定时任务(xxl-job)采用线程池的方式多线程请求第三方拉取数据&#xff0c;网络框架使用okhttp3。 问题&am…

改进YOLO5:结合CVPR2023最新 PConv |包含 YOLOv5 / YOLOv8 模型 YAML 文件

改进YOLO5:结合CVPR2023最新 PConv |包含 YOLOv5 / YOLOv8 模型 YAML 文件 一、论文总结PConv模块优势二、YOLOv51. yaml文件2. common代码文件三、YOLOv81. yaml2. modules文件添加3. Task文件4. 测试