C++二分查找算法的应用:最长递增子序列

简介: C++二分查找算法的应用:最长递增子序列

本文涉及的基础知识点

二分查找算法合集

单调映射

源码下载

点击下载源码

题目

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]

输出:4

解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

示例 2:

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

输出:4

示例 3:

输入:nums = [7,7,7,7,7,7,7]

输出:1

参数范围

1 <= nums.length <= 2500

-104 <= nums[i] <=104

暴力解法

分析

m_vRet[i],记录以nums[i]结尾的最长严格递增系列。计算m_vRet[i]的方法:nums[j] < nums[i]中最大m_vRet[j]+1。如果不存在合法的j,则m_vRet[i]等于1。

下表以{1,2,6,5,4,5}

i

m_vRet[0,i),加粗表示nums[j]<nums[i]

m_vRet[i]

0

1

1

1

2{1,2}

2

1 2

3{1,2,6}

3

1 2 3

3{1,2,5}

4

1 2 3 3

3{1,2,4}

5

1 2 3 3 3

4{1,2,4,5}

两层循环,分别枚举i和j,故总时间复杂度是O(n2)。

代码

class Solution {
public:
         int lengthOfLIS(vector<int>& nums) {
                   m_c = nums.size();
                   m_vRet.resize(m_c);
                   for (int i = 0; i < m_c; i++)
                   {
                            int iPreLen = 0;
                            for (int j = 0; j < i; j++)
                            {
                                     if (nums[j] >= nums[i])
                                     {
                                               continue;
                                     }
                                     iPreLen = max(iPreLen, m_vRet[j]);
                            }
                            m_vRet[i] = iPreLen + 1;
                   }
                   return *std::max_element(m_vRet.begin(), m_vRet.end());
         }
         vector<int> m_vRet;
         int m_c;
};

有序映射

分析

如果nums[j1] > nums[j2],且m_vRet[j1] <= m_vRet[j2],那么j1被j2淘汰。以nums[j]为key,m_vRet[j]为值,创建有序映射。key和value都是升序。

下表以{1,2,6,5,4,5,5}为列来说明,加粗表示新增加,删除线表示删除。

{1,1}

{1,1},{2,2}

{1,1},{2,2},{6,3}

{1,1},{2,2},{5,3},{6,3}

{1,1},{2,2},{4,3},{5,3}

{1,1},{2,2},{4,3},{5,4}

{1,1},{2,2},{4,3},{5,4}

代码

class Solution {
public:
         int lengthOfLIS(vector<int>& nums) {
                   m_c = nums.size();
                   m_vRet.resize(m_c);
                   std::map<int, int> mValueLen = { {-1000 * 1000,0} };
                   for (int i = 0; i < m_c; i++)
                   {
                            //计算以nums[i]结尾的最长长度
                            auto it = mValueLen.lower_bound(nums[i]);
                            const int iLen = std::prev(it)->second + 1;
                            m_vRet[i] = iLen;
                            //如果nums[j] >= nums[j],且长度小于等于删除
                            auto ij = it;
                            for (; (ij != mValueLen.end()) && (ij->second <= iLen); ++ij);
                            mValueLen.erase(it, ij);
                            //如果nums[i]存在,说明旧值比当前值大,不能处理
                            if (!mValueLen.count(nums[i]))
                            {
                                     mValueLen[nums[i]] = iLen;
                            }
                   }
                   return *std::max_element(m_vRet.begin(), m_vRet.end());
         }
         vector<int> m_vRet;
         int m_c;
};

其它

学院课程

基础算法的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


相关文章
|
2月前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
207 80
|
1月前
|
负载均衡 算法 安全
探秘:基于 C++ 的局域网电脑控制软件自适应指令分发算法
在现代企业信息化架构中,局域网电脑控制软件如同“指挥官”,通过自适应指令分发算法动态调整指令发送节奏与数据量,确保不同性能的终端设备高效运行。基于C++语言,利用套接字实现稳定连接和线程同步管理,结合实时状态反馈,优化指令分发策略,提升整体管控效率,保障网络稳定,助力数字化办公。
52 19
|
1月前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
52 5
|
1月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
49 2
|
2月前
|
机器学习/深度学习 算法
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。
|
2月前
|
存储 算法 安全
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
|
1月前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
2月前
|
算法 索引
【算法】——二分查找合集
二分查找基础模版和进阶模版,查找元素位置,搜索插入位置,x的平方根,山脉数组的峰顶索引,寻找峰值,点名
|
2月前
|
算法 安全 C++
用 C++ 算法控制员工上网的软件,关键逻辑是啥?来深度解读下
在企业信息化管理中,控制员工上网的软件成为保障网络秩序与提升办公效率的关键工具。该软件基于C++语言,融合红黑树、令牌桶和滑动窗口等算法,实现网址精准过滤、流量均衡分配及异常连接监测。通过高效的数据结构与算法设计,确保企业网络资源优化配置与安全防护升级,同时尊重员工权益,助力企业数字化发展。
65 4
|
4月前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。