子序列问题

目录

最长递增子序列

摆动序列

最长递增子序列的个数

最长数对链

最长定差子序列

最长的斐波那契子序列的长度

最长等差数列

等差数列划分II-子序列


声明:接下来主要使用动态规划来解决问题!!!

最长递增子序列

题目

思路

接下来,我们将屡试不爽的尝试使用以某个位置为结尾来分析问题

状态表示:dp[i]表示以i位置为结尾的递增序列中,最长子序列的长度。

状态转移方程:

初始化:全都初始化为1.

填表顺序:从左往右。

返回值:dp表中最大值。

代码

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int n=nums.size();vector<int> dp(n,1);for(int i=1;i<n;i++)for(int j=0;j<i;j++)if(nums[j]<nums[i])dp[i]=max(dp[i],dp[j]+1);return *max_element(dp.begin(),dp.end());}
};
摆动序列

题目

思路

我们依旧屡试不爽的尝试使用以某个位置为结尾来分析问题。

以某个元素为结尾,此时可能呈“上升”趋势,也可能呈“下降”趋势,如果我们只是使用dp[i]来表示的话,并不能表达出这种趋势,下面我们使用两个dp表,分别为f[i]和g[i],意思分别为:

f[i]表示以i位置为结尾的子序列中,呈“上升”趋势的最长摆动序列的长度;

g[i]表示以i位置为结尾的子序列中,呈“下降”趋势的最长摆动序列的长度。

状态转移方程:

填表顺序:从左往右,两个表同时填。

返回值:两个表中的最大值。

代码

class Solution {
public:int wiggleMaxLength(vector<int>& nums) {int n=nums.size();vector<int> f(n,1);
//以I位置为结尾的所有子序列中,最后一个位置呈“上升”的最长递增子序列vector<int> g(n,1);
//以I位置为结尾的所有子序列中,最后一个位置呈“下降”的最长递增子序列for(int i=1;i<n;i++){for(int j=0;j<i;j++){if(nums[j]>nums[i])g[i]=max(g[i],f[j]+1);if(nums[j]<nums[i])f[i]=max(f[i],g[j]+1);}}int a=*max_element(f.begin(),f.end());int b=*max_element(g.begin(),g.end());return max(a,b);}
};
最长递增子序列的个数

题目

思路

我们依旧屡试不爽的尝试使用以某个位置为结尾来分析问题。

但是在分析这道题之前,我们先讲解一种“思想”,比如找出一个数组中最大值出现的次数,我们可能会先遍历一遍找出最大值,然后再遍历一遍找出最大值出现的次数。

但是我们不妨改变一下做法:定义两个变量,maxval用来保存已遍历过位置的最大值,count用来保存最大值出现的次数。

当nums[i]<maxval,直接无视;

当nums[i]=maxval,count++;

当nums[i]>maxval,count=1,maxval=nums[i]。

下面将上面这种思路用到解题中。

状态表示:len[i]表示以i位置为结尾的子序列中,最长递增子序列的长度;

                  count[i]表示以i位置为结尾的子序列中,最长递增子序列出现的次数。

状态转移方程:

初始化:全都初始化为1.

填表顺序:从左往右。

返回值;最大长度出现的次数。

代码

class Solution {
public:int findNumberOfLIS(vector<int>& nums) {int n=nums.size();vector<int> len(n,1);vector<int> count(n,1);for(int i=1;i<n;i++)for(int j=0;j<i;j++){if(nums[j]<nums[i]){if(len[j]+1==len[i]) count[i]+=count[j];else if (len[j]+1>len[i]){len[i]=len[j]+1;count[i]=count[j];}}}int maxlen=len[0],ans=1;for(int i=1;i<n;i++){if(len[i]==maxlen) ans+=count[i];else if(len[i]>maxlen){ans=count[i];maxlen=len[i];}}return ans;}
};
最长数对链

题目

思路

我们依旧屡试不爽的尝试使用以某个位置为结尾来分析问题。

但是在解决问题前,我们先回顾之前的题目,在确定以某个位置为结尾时,状态是确定的,只需考虑该位置之前的元素,但是这道题不一样,可能还需要考虑该位置后面的元素,为了解决这个问题,我们先根据数对的第一个元素对数对进行从小到大排序,这样就不必再考虑确定了某位置为结尾还需考虑该位置之后元素的情况了。

接下来,就和《最长递增子序列》这道题一模一样了。

 

状态表示:dp[i]表示以i位置为结尾的递增序列中,最长子序列的长度。

状态转移方程:

初始化:全都初始化为1.

填表顺序:从左往右。

返回值:dp表中最大值。

代码

class Solution {
public:int findLongestChain(vector<vector<int>>& pairs) {sort(pairs.begin(),pairs.end());int n=pairs.size();vector<int> dp(n,1);for(int i=1;i<n;i++)for(int j=0;j<i;j++){if(pairs[j][1]<pairs[i][0])dp[i]=max(dp[i],dp[j]+1);}return *max_element(dp.begin(),dp.end());}
};
最长定差子序列

题目

思路

我们依旧屡试不爽的尝试使用以某个位置为结尾来分析问题。

下面在解决本题时,使用优化的方法来解决,使用哈希表来代替dp表,哈希表的K代表元素,V代表以该元素为结尾的等差子序列长度。

代码

class Solution {
public:int longestSubsequence(vector<int>& arr, int difference) {int n=arr.size();unordered_map<int,int> hash;hash[arr[0]]=1;int ret=1;for(int i=1;i<n;i++){hash[arr[i]]=hash[arr[i]-difference]+1;ret=max(ret,hash[arr[i]]);}return ret;}
};
最长的斐波那契子序列的长度

题目

思路

我们依旧屡试不爽的尝试使用以某个位置为结尾来分析问题。

如果定义的是一维dp,我们会发现不能确定连续三个斐波那契数,因此我们使用二维dp来解决。

其中0<i<j<n-1,并且对于c+a=b,c有三种情况,c在a之前,c在a和b之间,c不存在。 

为了便于更快确定c是否存在并且在哪个位置,使用哈希表来存储每个值的位置。

状态表示:dp[i][j]表示以i,j位置为结尾的斐波那契数列的长度。

状态转移方程:if(hash.count(arr[j]-arr[i]) && hash[arr[j]-arr[i]]<i)

                                dp[i][j]=dp[hash[arr[j]-arr[i]]][i]+1.

初始化:全都初始化为2.

返回值:如果最大长度是2则返回0,否则返回最大长度。

代码

class Solution {
public:int lenLongestFibSubseq(vector<int>& arr) {int n=arr.size();unordered_map<int,int> hash;for(int i=0;i<n;i++)hash[arr[i]]=i;vector<vector<int>> dp(n,vector(n,2));//dp[i][j]=dp[k][i]+1;int ret=2;for(int j=2;j<n;j++)for(int i=1;i<j;i++){if(hash.count(arr[j]-arr[i]) && hash[arr[j]-arr[i]]<i){dp[i][j]=dp[hash[arr[j]-arr[i]]][i]+1;ret=max(ret,dp[i][j]);}}return ret<3?0:ret;}
};
最长等差数列

题目

思路

我们依旧屡试不爽的尝试使用以某个位置为结尾来分析问题。

但是经过分析会发现使用一维dp是不能解决的,接下来尝试使用二维dp来解决。

其中0<i<j<n-1,并且对于c+a=b,c有三种情况,c在a之前,c在a和b之间,c不存在。  

状态表示:dp[i][j]表示以i,j为结尾的所有等差数列中,数列的最大长度。

状态转移方程:

int a=2*nums[i]-nums[j];

if(hash.count(a))

        dp[i][j]=dp[hash[a]][i]+1;

初始化:全部都初始化为2.

填表顺序:从上到下,从左往右,固定倒数第二个位置,枚举倒数第一个位置。

为什么不是固定倒数第一个位置,枚举倒数第二个位置,而是固定倒数第二个位置,枚举倒数第一个位置,是因为这样的话,需要不断的更新哈希表。

代码

class Solution {
public:int longestArithSeqLength(vector<int>& nums) {int n=nums.size();unordered_map<int,int> hash;hash[nums[0]]=0;vector<vector<int>> dp(n,vector<int>(n,2));int ret=2;for(int i=1;i<n-1;i++){for(int j=i+1;j<n;j++){if(hash.count(2*nums[i]-nums[j])){dp[i][j]=dp[hash[2*nums[i]-nums[j]]][i]+1;ret=max(ret,dp[i][j]);}}hash[nums[i]]=i;}return ret;}
};
等差数列划分II-子序列

题目

思路

我们依旧屡试不爽的尝试使用以某个位置为结尾来分析问题。

但是经过分析会发现使用一维dp是不能解决的,接下来尝试使用二维dp来解决。

其中0<i<j<n-1,并且对于c+a=b,c有三种情况,c在a之前,c在a和b之间,c不存在。  

状态表示:dp[i][j]表示以i,j为结尾的所有等差数列中,数列的个数。

状态转移方程:

long long a=(long long)2*nums[i]-nums[j];

if(hash.count(a))

for(int x:hash[a])

        if(x<i)

              dp[i][j]+=dp[x][i]+1;

初始化:全都初始化为0.

填表顺序:固定倒数第一个位置,枚举倒数第二个位置。 

代码

class Solution {
public:int numberOfArithmeticSlices(vector<int>& nums) {int n=nums.size();unordered_map<long long,vector<int>> hash;for(int i=0;i<n;i++)hash[nums[i]].push_back(i);vector<vector<int>> dp(n,vector<int>(n));int ret=0;for(int j=2;j<n;j++){for(int i=1;i<j;i++){long long a=(long long)2*nums[i]-nums[j];if(hash.count(a)){for(int x:hash[a]){if(x<i)dp[i][j]+=dp[x][i]+1;}ret+=dp[i][j];}}}return ret;}
};

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

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

相关文章

如何通过文件分发系统,实现能源电力企业文件的安全分发流转?

随着企业业务的快速发展&#xff0c;能源电力企业会在全国乃至全球&#xff0c;设立总部-分部-办事处/网点等多层级的结构&#xff0c;因此会涉及自动化的文件分发的业务场景。文件分发系统是一种将文件从一个地方自动传输到多个接收者的过程&#xff0c;可以提高工作效率&…

香港优才计划多少分获批成功率高?一文看懂各分数段获批情况!

有留意香港优才计划的朋友&#xff0c;应该都了解过&#xff0c;申请优才计划采用打分制&#xff0c;得分多少与最终获批有密不可分的关系。但有一点要提前清楚&#xff0c;申请优才不是得分越高就一定能获批&#xff0c;也不是得分低就一定没希望。 香港优才计划能否获批成功…

正确理解驱动电流与驱动速度

本文主要阐述了在驱动芯片中表征驱动能力的关键参数&#xff1a;驱动电流和驱动时间的关系&#xff0c;并且通过实验解释了如何正确理解这些参数在实际应用中的表现。 驱动芯片概述 功率器件如MOSFET、IGBT需要驱动电路的配合从而得以正常地工作。图1显示了一个驱动芯片驱动一…

迅狐抖音机构号授权矩阵系统源码

在数字化营销的浪潮中&#xff0c;抖音以其独特的短视频形式迅速崛起&#xff0c;成为品牌传播和用户互动的重要平台。迅狐抖音机构号授权矩阵系统源码作为一项创新技术&#xff0c;为品牌在抖音上的深度运营提供了强大支持。 迅狐抖音机构号授权矩阵系统源码简介 迅狐抖音机…

新版Android Studio中设置gradle的JDK版本

旧版android studio 在旧版&#xff08;具体哪个版本号之前搞不清了&#xff09;中设置JDK版本在>File——>Project Structure——>SDK location——>Gradle Setting——>Gradle SDK 新版android studio 某次更新后发现SDK location下找不到Gradle Setting选项…

通过Vxlan实现数据中心互联有感

随着企业的发展&#xff0c;为满足跨地域运营、用户接入、异地灾备等场景&#xff0c;越来越多的企业通常在多地域部署多个数据中心。 数据中心互联DCl(Data Center Interconnection)是不同数据中心VM之间互相通信的一种解决方案使用VXLAN、BGP EVPN等技术&#xff0c;使数据中…

uniapp+uview实现手机端上传照片带水印(保姆级全过程)

目录 前言&#xff1a;实现思路 步骤一、在界面使用uview的u-upload组件、放置canvas标签 步骤二、在afterRead方法中获取照片url&#xff0c;并创建画布生成水印&#xff0c;再将生成水印的照片上传到服务器 1、afterRead方法 2、照片加水印的方法 3、上传照片至服务器 …

zookeeper加入开机启动项

Windows的任务计划程序&#xff08;Task Scheduler&#xff09;是一个强大的工具&#xff0c;允许你安排程序在特定时间自动运行&#xff0c;包括开机时。 打开任务计划程序&#xff1a; 按下Win R键&#xff0c;打开“运行”对话框。输入taskschd.msc并回车&#xff0c;打开…

Python编写网络嗅探器程序捕获和显示IP数据包的头部信息

Python编写网络嗅探器程序捕获和显示IP数据包的头部信息 抓取网络数据包并解析其中的IP首部信息&#xff0c;并通过GUI界面显示解析结果。程序展示了如何使用Python的socket和ctypes库来捕获和解析网络数据包,并使用Tkinter创建一个简单的GUI界面来显示捕获到的IP头部信息。这…

日志服务SLS入门指南

日志服务SLS入门指南 什么是日志服务SLSNginx日志采集部署Nginx创建Logstore接入数据 数据脱敏创建脱敏Logstore数据加工 告警设置添加告警规则查看告警 写在最后 什么是日志服务SLS 在说到日志服务SLS之前&#xff0c;首先了解一下什么是日志服务SLS&#xff1f;日志服务SLS是…

PHP项目中的前端页面随意点击卡片后会重定向到首页或登录页

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

pycharm使用micropython

一、打开设置 2、搜索micropython、安装、重启 3、第5步需要设置成你插的电脑USB口&#xff0c;一个一个试 4、 5、 6、OK

手机数据恢复篇:优秀的 iPhone 数据恢复汇总

如果您不幸遭遇 iPhone 死机、进水或死机&#xff0c;一切还不算晚。您可以使用 iPhone 数据恢复应用恢复文件、照片、应用数据、消息等。 使用以下选项&#xff0c;您可以恢复 iPhone 上的少量内容、特定项目或所有内容。有些应用程序甚至提供修复工具来修复最初导致数据丢失…

这组杭州亚运会可视化大屏,绝对引领了时代。

本期分享杭州亚运会的可视化大屏&#xff0c;非常的震撼&#xff0c;杭州不愧为我国互联网最发达的的城市之一。 怒赞&#xff01;&#xff01;&#xff01;

暑期旅游怎么玩?开发旅游小程序让出行变简单

暑假正值旅游旺季&#xff0c;旅游小程序的出现为旅行带来了许多便利。随着移动互联网的发展&#xff0c;旅游行业也在不断寻求创新与变革。旅游小程序为游客提供了更加便捷的旅行体验&#xff0c;通过旅游小程序&#xff0c;用户可以了解旅游信息、旅游服务、在线咨询等&#…

【Dison夏令营 Day 13】使用 Python 创建扫雷游戏

在本文中&#xff0c;我们将介绍如何使用 Python 语言创建自己的基于终端的扫雷程序。 关于游戏 1992年4月6日&#xff0c;扫雷和纸牌、空当接龙等小游戏搭载在Windows 3.1系统中与用户见面&#xff0c;主要目的是让用户训练使用鼠标。扫雷是一款单人游戏&#xff0c;这个游戏…

Linux系统下anaconda的安装与Pytorch环境的下载

首先&#xff0c;在命令行通过cd命令&#xff0c;进入用户文件夹 cd xxx/xxx/username进入anaconda官网https://repo.anaconda.com/archive/&#xff0c;寻找anaconda下载包资源&#xff0c;这里选择最新的anaconda下载包 Anaconda3-2024.06-1-Linux-x86_64.sh 在命令行执行安…

气膜建筑如何在文化旅游行业中应用—轻空间

一、气膜建筑简介 气膜建筑是一种新型建筑形式&#xff0c;其主要结构由高强度膜材、空气支撑系统和固定系统组成。通过不断向膜体内部充气&#xff0c;使其形成稳定的内部压力来支撑整个建筑结构。气膜建筑因其建设速度快、成本相对较低、环保节能等优点&#xff0c;近年来在各…

阶段三:项目开发---大数据开发运行环境搭建:任务3:安装配置Hadoop集群

任务描述 知识点&#xff1a;安装配置Hadoop 重 点&#xff1a; 安装配置Hadoop 难 点&#xff1a;无 内 容&#xff1a; Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下&#xff0c;开发分布式程序。充分利用集群的威…

Linux系统编程——线程控制

目录 一&#xff0c;关于线程控制 二&#xff0c;线程创建 2.1 pthread_create函数 2.2 ps命令查看线程信息 三&#xff0c;线程等待 3.1 pthread_join函数 3.2 创建多个线程 3.3 pthread_join第二个参数 四&#xff0c;线程终止 4.1 关于线程终止 4.2 pthread_exit…