C++二分查找算法:132 模式

news2024/10/6 1:40:08

说明

本篇是视频课程的讲义,可以看直接查看视频。也可以下载源码,包括空源码。

题目

给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]nums[j] nums[k] 组成,并同时满足:i < j < k nums[i] < nums[k] < nums[j]

如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false

示例 1

输入:nums = [1,2,3,4]

输出:false

解释:序列中不存在 132 模式的子序列。

示例 2

输入:nums = [3,1,4,2]

输出:true

解释:序列中有 1 132 模式的子序列: [1, 4, 2]

示例 3

输入:nums = [-1,3,2,0]

输出:true

解释:序列中有 3 132 模式的的子序列:[-1, 3, 2][-1, 3, 0] [-1, 2, 0]

参数范围

n == nums.length

1 <= n <= 2 * 105

-109 <= nums[i] <= 109

分析

分两步。

第一步计算12存储到m_v2To1。m_v2To1[j]等于i表示nums[j] >=nsum[i],如果有多个合法的i,取最小值,如果不存在,m_v2To1[j]=m_c。mValueIndexkey对应数组值nums[i]value对应数组索引ii[0,j)。由于是从左向右寻找小于某数的数,如果i1>=i0,且nums[i1] >= nums[i0],则i1被淘汰。淘汰后,mValueIndex中的数组值按升序排序,数组索引按降序排序。如果mValueIndex中存在数组值小于iValue的数,那说明存在值、索引都比i小的数,i被淘汰。大于等于i的索引还未添加。如果不存在,不需要判断当前值和索引是否淘汰已有值,因为:索引是按从小到大添加的。添加时需要判断当真值,是否存在。如果存在,则其索引一定小于当前索引,无需添加。

第二步,遍历m_v2To1,寻找是否存在kmValueIndexkey对应数组值nums[k]value对应数组索引kj[0,i)。由于是从右向左寻找大于某数的数,所以数组值和索引都小的值和索引被淘汰。淘汰后,mValueIndex中的数组值按升序排序,数组索引按降序排序。由于mValueIndex已有数据中的索引小于当前索引,所以只需要考虑淘汰旧值(数组值小于等于当前数组值)。k需要符合以下三个条件:

条件一

nums[k] > nums[j]

条件二

k > i(即v2To1[j])

条件三

k < j (一定符合,不符合的还没添加)

auto it = mValueIndex.upper_bound(iValue);

后[it, mValueIndex.end()) 都符合条件一,由于索引是降序排序,所以只需要判断it->second是否大于i

核心代码

class Solution {

public:

         bool find132pattern(vector<int>& nums) {

                   m_c = nums.size();

                   m_v2To1.assign(m_c, m_c);

                   {

                            map<int, int> mValueIndex;//key按升序,value按降序排序

                            for (int j = 0; j < m_c; j++)

                            {

                                     const int iValue = nums[j];

                                     auto it = mValueIndex.lower_bound(iValue);

                                      if (mValueIndex.begin() != it)

                                     {

                                               auto itPre = std::prev(it);

                                               m_v2To1[j] = itPre->second;

                                               continue;//keyvalue都小于等于iValueii被淘汰

                                     }

                                     //删除keyvalue都大于等于iValuei

                                     if (!mValueIndex.count(nums[j]))

                                     {

                                               mValueIndex[nums[j]] = j;

                                     }

                            }

                   }

                   //遍历v[2],看是否存在3

                   {

                            map<int, int> mValueIndex;//1323,从右向左找大于2的值。key按升序,value按降序排序

                            for (int j = 0; j < m_c; j++)

                            {

                                     const int iValue = nums[j];

                                     auto it = mValueIndex.upper_bound(iValue);

                                     if (mValueIndex.end() != it)

                                     {

                                               if (it->second > m_v2To1[j])

                                               {

                                                        m_iIndex3 = it->second;

                                                        return true;

                                               }

                                     }

                                     while (mValueIndex.size() && (mValueIndex.begin()->first <= iValue))

                                     {

                                               mValueIndex.erase(mValueIndex.begin());

                                     }

                                     mValueIndex[iValue] = j;

                            }

                   }

                   return false;

         }

         vector<int> m_v2To1;//v[i]等于j表示nums[i] >=nsum[j],如果有多个合法的j,取最小值,如果不存在,v[i]=m_c

         int m_iIndex3=-1;      

         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<int> nums;

         bool res;

         {

                   Solution slu;

                   nums = { 3,5,0,3,4 };          

                   res = slu.find132pattern(nums);

                   Assert(vector<int>{5, 0, 5, 2,0}, slu.m_v2To1);

                   Assert(1, slu.m_iIndex3);

                   Assert(true, res);

         }

         {

                   nums = { 1 ,2, 3,4 };

                   res = Solution().find132pattern(nums);

                   Assert(false, res);

         }

         {

                   Solution slu;

                   nums = { 3,1,4,2 };

                   res = slu.find132pattern(nums);

                   Assert(vector<int>{4, 4, 0, 1}, slu.m_v2To1);

                   Assert(2, slu.m_iIndex3);

                   Assert(true, res);

         }

         {

                   Solution slu;

                   nums = { -1,3,2,0 };

                   res = slu.find132pattern(nums);

                   Assert(vector<int>{4, 0, 0, 0}, slu.m_v2To1);

                   Assert(1, slu.m_iIndex3);

                   Assert(true, res);

         }

         //CConsole::Out(res);

}

https://img-blog.csdnimg.cn/ea2601b3918f4aef836b5fe30da2ebf7.gif#pic_center#pic_center

其它

学院课程

基础算法的C++实现课程,请点击下面的CSDN学院的链接。讲义有算法详解。

2024年1月15之前完全免费,之后绝大部分免费

https://edu.csdn.net/course/detail/38771

C#入职培训

此课程的目的:让新同事更快完成从学生到C#程序员的转换,更快上手完成C#的开发工作。

https://edu.csdn.net/course/detail/38768

C++入职培训

让新同事更快完成从学生到C++程序员的转换,更快上手完成C++的开发工作。

https://edu.csdn.net/course/detail/32049

运行验证环境

Win10 VS2022 Ck++17 或win7 VS2019 C++17

每天都补充正能量

好好学习,天天向上。

事无终始,无务多业。

是故置本不安者,无务丰末。

相关下载

如果你时间宝贵,只想看精华,请到CSDN下载频道下载《闻缺陷则喜算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653

https://img-blog.csdnimg.cn/f95ddae62a4e43a68295601c723f92fb.gif#pic_center

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

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

相关文章

【每日一题】—— B. Deja Vu(Codeforces Round 907 (Div. 2))(暴力枚举、队列)

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

2023.11.13-istio之故障注入流量拆分流量镜像熔断-oss

istio之故障注入&流量拆分&流量镜像&熔断 目录 文章目录 istio之故障注入&流量拆分&流量镜像&熔断目录本节实战1、故障注入注入 HTTP 延迟故障&#x1f6a9; 实战&#xff1a;注入 HTTP 延迟故障-2023.11.12(测试成功) 注入 HTTP abort 故障&#x1f6…

【算法】繁忙的都市(Kruskal算法)

题目 城市C是一个非常繁忙的大都市&#xff0c;城市中的道路十分的拥挤&#xff0c;于是市长决定对其中的道路进行改造。 城市C的道路是这样分布的&#xff1a; 城市中有 n 个交叉路口&#xff0c;编号是 1∼n &#xff0c;有些交叉路口之间有道路相连&#xff0c;两个交叉…

【案例】超声波测距系统设计

1.1 总体设计 1.1.1 概述 学习了明德扬至简设计法和明德扬设计规范&#xff0c;本人用FPGA设计了一个测距系统。该系统采用超声波进行测量距离再在数码管上显示。在本案例的设计过程中包括了超声波的驱动、三线式数码管显示等技术。经过逐步改进、调试等一系列工作后&#xf…

通信世界扫盲基础二(原理部分)

上次我们刚学习了关于通信4/G的组成和一些通识&#xff0c;今天我们来更深层次了解一些原理以及一些新的基础~ 目录 专业名词 LTE(4G系统) EPC s1 E-UTRAN UE UU X2 eNodeB NR(5G系统) NGC/5GC NG NG-RAN Xn gNodeB N26接口 手机的两种状态 空闲态 连接态 …

HCIP-双点双向重发布

实验拓扑 要求&#xff1a;全网没有次优路径、且尽量负载均衡。 设备配置 R1 [V200R003C00] #sysname R1 #snmp-agent local-engineid 800007DB03000000000000snmp-agent #clock timezone China-Standard-Time minus 08:00:00 # portal local-server load flash:/portalpage.…

RT-DETR算法改进:更换损失函数DIoU损失函数,提升RT-DETR检测精度

💡本篇内容:RT-DETR算法改进:更换损失函数DIoU损失函数 💡本博客 改进源代码改进 适用于 RT-DETR目标检测算法(ultralytics项目版本) 按步骤操作运行改进后的代码即可🚀🚀🚀 💡改进 RT-DETR 目标检测算法专属 文章目录 一、DIoU理论部分 + 最新 RT-DETR算法…

【数据库开发】DataX开发环境的安装部署(Python、Java)

文章目录 1、简介1.1 DataX简介1.2 DataX功能1.3 支持的数据通道 2、DataX安装配置2.1 DataX2.2 Java2.3 Python 3、DataX Web安装配置3.1 mysql3.2 DataX Web3.2.1 简介3.2.2 架构图3.2.3 依赖环境3.2.4 安装 4、入门使用4.1 DataX自带打印示例测试4.2 DataX生成任务模板文件4…

配置开启Docker2375远程连接与解决Docker未授权访问漏洞

一、配置开启Docker远程连接 首先需要安装docker,参考我这篇文章&#xff1a;基于CentOS7安装配置docker与docker-compose 配置开启Docker远程连接的步骤&#xff1a; //1-编辑/usr/lib/systemd/system/docker.service 文件 vim /usr/lib/systemd/system/docker.service //2…

Linux socket编程(1):套接字、字节序和地址结构体

套接字(socket)是一种使用标准Unix文件描述符与其他程序进行通信的方式&#xff0c;它在实际的应用中都十分常用。所以从这一篇文章开始&#xff0c;我将详细介绍一下Linux环境下的socket的用法。本篇文章将介绍套接字、字节序和地址结构体的相关知识。 文章目录 1 什么是套接字…

深入理解指针(一)

目录 内存和地址 内存 如何理解编址 指针变量和地址 取地址操作符&#xff08;&&#xff09; 指针变量和解引用操作符&#xff08;*&#xff09; 指针变量 如何拆解指针类型 解引用操作符 指针变量的大小 ​编辑 指针变量类型的意义 指针的解引用 指针-整…

sass 封装媒体查询工具

背景 以往写媒体查询可能是这样的&#xff1a; .header {display: flex;width: 100%; }media (width > 320px) and (width < 480px) {.header {height: 50px;} }media (width > 480px) and (width < 768px) {.header {height: 60px;} }media (width > 768px) …

【Java】定时任务 - Timer/TimerTask 源码原理解析

一、背景及使用 日常实现各种服务端系统时&#xff0c;我们一定会有一些定时任务的需求。比如会议提前半小时自动提醒&#xff0c;异步任务定时/周期执行等。那么如何去实现这样的一个定时任务系统呢&#xff1f; Java JDK提供的Timer类就是一个很好的工具&#xff0c;通过简单…

【Qt】撤销/恢复的快捷键

使用Qt的时候&#xff0c;有时需要撤销修改的代码&#xff0c;但可能回撤过头了。 下面提供2个快捷键&#xff0c;当撤销过头时&#xff0c;可恢复撤销内容。 撤销的快捷键是 CtrlZ 恢复/向前的快捷键是 CtrlShiftZ 我们可以自定义快捷键。 点击【工具】->【选项】 点击…

基于XML的声明式事务

场景模拟 参考基于注解的声明式事务 修改Spring的配置文件 将Spring配置文件中去掉tx:annotation-driven标签&#xff0c;并添加配置&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org…

解决VSCode中文乱码问题

解决VSCode乱码问题 1.问题描述&#xff1a;2.原因分析&#xff1a;3.解决方案&#xff1a;1&#xff09;解决步骤2&#xff09;深入分析 4.总结 1.问题描述&#xff1a; 最近用vscode的时候突然发现中文字符出现乱码。在网上找了好几种方法都不行&#xff0c;用各种编码格式打…

【机器学习】八、规则学习

知识图谱与基本概念 基本概念 规则学习定义&#xff1a;从训练数据中学习出一组能用于对未见示例进行判别的规则。 规则定义&#xff1a;规则一般是&#xff1a;语义明确、能描述数据分布所隐含的客观规律或领域概念。 逻辑规则定义&#xff1a;⊕←?1⋀?2⋀?3…⋀??⊕…

file2Udp增量日志转出Udp简介

https://gitee.com/tianjingle/file2udp 很多时候服务产生的日志需要进行汇总&#xff0c;这种统一日志处理的方式有elb&#xff0c;而且很多日志组件也支持日志转出的能力。但是从广义上来说是定制化的&#xff0c;我们需要一个小工具实现tail -f的能力&#xff0c;将增量日志…

2024最新基于物联网单片机毕业设计选题汇总(合集)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

大数据技术与原理实验报告(MapReduce 初级编程实践)

MapReduce 初级编程实践 验环境&#xff1a; 操作系统&#xff1a;Linux&#xff08;建议Ubuntu16.04&#xff09;&#xff1b; Hadoop版本&#xff1a;3.2.2&#xff1b; &#xff08;一&#xff09;编程实现文件合并和去重操作 对于两个输入文件&#xff0c;即文件 A 和…