当前位置: 首页 > news >正文

【dp】最长递增子序列

文章目录

    • 方法一:动态规划
    • 方法二:贪心 + 二分查找
    • 构造最长递增子序列

在这里插入图片描述

方法一:动态规划

  • dp[i]:末尾元素为arr[i]的最长子序列的长度

在这里插入图片描述

从0遍历到i - 1,若遍历到的元素小于当前值arr[i],表示当前值arr[i]可以和前面的某个值组成递增序列,则尝试更新dp[i]

int LIS(vector<int>& arr) {int n = arr.size();if(n == 0) return 0;vector<int> dp(n, 1);int ans = 1;for(int i = 1; i < n; i++){for(int j = 0; j < i; j++){if(arr[j] < arr[i]){dp[i] = max(dp[i], dp[j] + 1);}}ans = max(ans, dp[i]);}return ans;
}

时间复杂度: O ( N 2 ) O(N^2) O(N2)

方法二:贪心 + 二分查找

我们考虑维护一个数组 min_tails,min_tails[i]表示长度为i + 1的递增子序列末尾元素的最小值,min_tails并不是记录arr中的递增子序列

在这里插入图片描述

看最后一个g数组,g[2]=3,表示长度为3的递增子序列末尾的最小值为3。长度为3的递增子序列有[1,6,7]、[1,2,4]、[1,2,5]、[1,2,3]

为什么min_tails数组中要维护各个不同长度递增子序列末尾元素的最小值呢?

min_tails数组中维护各个不同长度递增子序列末尾元素的最小值时,arr的后续元素可以和不同长度子序列末尾的最小值比较,从而确定后续元素可以加入哪个子序列,成为新的递增子序列

在这里插入图片描述

int LIS(vector<int>& arr) {int n = arr.size();if(n == 0) return 0;vector<int> tails(n);min_tails[0] = arr[0];int len = 1;for(int i = 1; i < n; i++){// 如果当前元素比长度为len的子序列末尾元素的最小值大,说明当前元素可以和长度为len的子序列组成新的递增子序列if(min_tails[len - 1] < arr[i]){min_tails[len] = arr[i];len++;continue;}// 二分:用arr[i]更新tails中最靠左侧的大于arr[i]的值int l = 0;int r = len;while(l < r){int mid = l + (r - l) / 2;if(min_tails[mid] < arr[i]) l = mid + 1;  // 用l找第一个比arr[i]大的值,也可以找最后一个小于等于arr[i]的值else r = mid;}min_tails[l] = arr[i];}return len;
}

构造最长递增子序列

在这里插入图片描述

max_len相同时取最小的,ans初始化为len个元素,从后往前填写。如果max_len相同,靠后的arr[i]一定更小,若靠后的arr[i]更大,那max_len就不能相同了。比如:

在这里插入图片描述

class Solution {
public:vector<int> LIS(vector<int>& arr) {int n = arr.size();if(n < 2) return arr;vector<int> min_tails(n); // min_tails[i]:长度为i+1的最长递增子序列末尾元素的最小值min_tails[0] = arr[0];int len  = 1;             // 当前最长递增子序列的长度vector<int> max_len(n);   // max_len[i]:表示以arr[i]结尾的最长递增子序列的长度max_len[0] = 1;for(int i = 1; i < n; i++){// 当前元素arr[i]已经比当前最长递增子序列末尾元素的最小值要大,说明可以和当前递增子序列组成新的递增子序列if(arr[i] > min_tails[len - 1]){min_tails[len] = arr[i];max_len[i] = len + 1; // arr[i]可以增加最长递增子序列的长度len++;continue;}// arr[i]不能和当前最长递增子序列组成新的递增子序列,可以尝试用arr[i]和较短的递增子序列组成新的递增子序列(极端情况下,arr[i]自己组成长度为1的递增子序列)// 在[l, r)之间找第一个大于arr[i]的位置,说明arr[i]可以和前面较短的递增子序列组成新的递增子序列,用arr[i]更新第一个大于arr[i]的元素,即让某递增子序列的长度不变,而末尾元素变小int l = 0;int r = len;while(l < r){int mid = l + (r - l) / 2;if(min_tails[mid] < arr[i]) l = mid + 1;else r = mid;  // 不能是r = mid - 1,因为要找第一个大于arr[i]的值,此时min_tails[mid] >= arr[i],r = mid - 1会跳过大于arr[i]的min_tails[mid]}min_tails[l] = arr[i];max_len[i] = l + 1;  // arr[i]不能增加最长递增子序列的长度,min_tails[l]是第一个大于arr[i]的元素,即用arr[i]可以组成长度为l + 1的递增子序列}vector<int> ans(len);int idx = len - 1;// 只能按顺序填for(int i = n - 1; i >= 0; i--){// 遍历max_len数组,最大长度为idx + 1时才可填写ans[idx],max_len相同时必然取最靠后的arr[i],因为最靠后的最小if(max_len[i] == idx + 1){ans[idx] = arr[i];idx--;}}return ans;}
};

相关文章:

【dp】最长递增子序列

文章目录 方法一&#xff1a;动态规划方法二&#xff1a;贪心 二分查找构造最长递增子序列 方法一&#xff1a;动态规划 dp[i]&#xff1a;末尾元素为arr[i]的最长子序列的长度 从0遍历到i - 1&#xff0c;若遍历到的元素小于当前值arr[i]&#xff0c;表示当前值arr[i]可以和…...

docker容器:Docker-Compose

目录 一、Docker-Compose 1、Docker-Compose使用场景 2、Docker-Compose简介 3、Docker-Compose安装部署 4、YML文件编写注意事项 5、Compose配置常用字段 6、 Docker Compose 常用命令 7、Docker Compose 文件结构 8、docker Compose撰写nginx 镜像 9、docker Compos…...

如何使用DNS实现融合CDN功能

将托管DNS解决方案与CDN配对可为您的网站提供额外的性能、可靠性和灵活性。 域名系统&#xff08;DNS&#xff09;是一种用于计算机、服务或连接到Internet或专用网络的任何资源的分层分布式命名系统&#xff0c;它将各种信息与分配给每个参与实体的域名相关联&#xff0c;它基…...

有关实现深拷贝的四种方法

深拷贝与浅拷贝: 在开始之前我们需要先了解一下什么是浅拷贝和深拷贝&#xff0c;其实深拷贝和浅拷贝都是针对的引用类型&#xff0c;JS中的变量类型分为值类型&#xff08;基本类型&#xff09;和引用类型&#xff1b;对值类型进行复制操作会对值进行一份拷贝&#xff0c;而对…...

Mysql 高可用部署实践

mysql主从是如何备份的? 在MySQL主从复制架构下&#xff0c;备份通常需要在主库和从库上分别进行。 主库备份&#xff1a; 在主库上进行备份时&#xff0c;可以使用mysqldump等命令生成SQL文件&#xff0c;并将其保存到本地或者远程服务器上。备份过程中需要注意以下几点&a…...

IEEE-TMI:张孝勇团队开发小鼠精细脑结构自动分割的深度学习算法

近日&#xff0c;复旦大学类脑智能科学与技术研究院青年研究员张孝勇课题组联合德国亥姆霍兹慕尼黑研究中心&#xff0c;在医学图像处理领域顶尖期刊《IEEE医学影像汇刊》(IEEE Transactions on Medical Imaging&#xff0c;TMI) 发表了题为《MouseGAN&#xff1a;用于小鼠大脑…...

八股文之面向对象和面向过程的区别

面向对象&#xff08;Object-Oriented&#xff09;和面向过程&#xff08;Procedural&#xff09;是两种不同的编程思想。 面向过程是以任务为中心&#xff0c;将程序分解成一系列步骤&#xff0c;在每个步骤中定义一个函数来完成特定的任务。它主要关注程序执行的过程和如何组…...

SpringBoot使用Redis实现分布式缓存

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

Three——二、加强对三维空间的认识

Three——二、加强对三维空间的认识 接上个例子我们接着往下看 辅助观察坐标系 THREE.AxesHelper()的参数表示坐标系坐标轴线段尺寸大小&#xff0c;你可以根据需要改变尺寸。 使用方法&#xff1a; // AxesHelper&#xff1a;辅助观察的坐标系 const axesHelper new THRE…...

【Java】Java8接口中方法区别和使用

Java接口说明 jdk1.8之前接口只能是抽象方法。实现接口必须重写所有方法&#xff0c;比较麻烦。在java8中&#xff0c;支持default和static方法&#xff0c;这样&#xff0c;实现接口时&#xff0c;可以选择是否对default修饰的方法重写。 抽象方法 接口当中的抽象方法&#x…...

WPF 控件库Live Charts 折线图多折线比较问题处理

使用Live Charts功能对比多条折线时当Label不是一一对应时会发现折线无法对比如 Labels List<double> list2 new List<double>(); list2.Add(2.1); //x为0.5时 list2.Add(2.2); //x为0.6时 …...

接口优化方案

前言 最近随着国产化热潮&#xff0c;公司的用于营业的电脑全部从windows更换成了某国产化电脑&#xff0c;换成国产化之后&#xff0c;我们系统的前台web界面也由之前的jsp页面重构成vue.所以之前的一体式架构也变成了前后端分离的架构。但是在更换过程后&#xff0c;发现一些…...

《商用密码应用与安全性评估》第二章政策法规2.1网络空间安全形式与商业密码工作

一、国际国内网络空间安全形势 网络空间已成为与陆地、海洋、天空、太空同等重要的人类第五空间。 1.国际形势 网络空间安全纳入国家战略 网络攻击在国家对抗中深度应用 网络空间已逐步深入网络底层固件 2.国内形势 核心技术仍受制于人 信息产品存在巨大安全隐患 关…...

C#实现将文件、文件夹压缩为压缩包

C#实现将文件、文件夹压缩为压缩包 一、C#实现将文件、文件夹压缩为压缩包核心 1、介绍 Title&#xff1a;“基础工具” 项目&#xff08;压缩包帮助类&#xff09; Description步骤描述&#xff1a; 1、创建 zip 存档&#xff0c;该文档包含指定目录的文件和子目录&#xf…...

程序员跳槽,要求涨薪50%过分吗?

如果问在TI行业涨工资最快的方式是什么&#xff1f; 回答最多的一定是&#xff1a;跳槽&#xff01; 前段时间&#xff0c;知乎上这样一条帖子引发了不少IT圈子的朋友的讨论 &#xff0c;有网友提问 “程序员跳槽要求涨薪50%过分吗&#xff1f;” 截图来源于知乎&#xff0c;…...

Java核心技术 卷1-总结-10

Java核心技术 卷1-总结-10 通配符类型通配符概念通配符的超类型限定无限定通配符通配符捕获 通配符类型 通配符概念 通配符类型中&#xff0c;允许类型参数变化。 例如&#xff0c;通配符类型Pair<? extends Employee>表示任何泛型Pair类型&#xff0c;它的类型参数是…...

React Props

state 和 props 主要的区别在于 props 是不可变的&#xff0c;而 state 可以根据与用户交互来改变。 所以&#xff0c;有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。 props 使用 Demo.js &#xff1a; import React from reactfunct…...

【Hello Network】协议

作者&#xff1a;小萌新 专栏&#xff1a;网络 作者简介&#xff1a;大二学生 希望能和大家一起进步 本篇博客简介&#xff1a;简单介绍下协议并且设计一个简单的网络服务器 协议 协议的概念结构化数据传输序列化和反序列化网络版计算机服务端代码协议定制客户端代码服务线程执…...

零项目零科研,本科排名倒数,一战上岸上海交大电子与通信工程

笔者来自通信考研小马哥23上交819全程班学员 本科就读于哈工大&#xff08;威海&#xff09;&#xff0c;本科成绩很差&#xff0c;专业排名62/99&#xff0c;没有科研&#xff0c;没有实验室&#xff0c;没有项目&#xff0c;连最基本大家都会参加的科技立项我四年也没有参与…...

NOIP模拟赛 T3区间

题目大意 有 n n n个数字&#xff0c;第 i i i个数字为 a i a_i ai​。有 m m m次询问&#xff0c;每次给出 k i k_i ki​个区间&#xff0c;每个区间表示第 l i , j l_{i,j} li,j​到第 r i , j r_{i,j} ri,j​个数字&#xff0c;求这些区间中一共出现了多少种不同的数字。部…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...