您的位置:首页 > 产品设计 > UI/UE

最长递增子序列(longest increasing subsequence) 问题详解

2017-05-22 16:39 627 查看
最长递增子序列的定义:

按照序列元素的下标号,抽取一部分元素组成子序列,子序列中的元素之间为递增的关系(下标可以不连续)。其中长度最长的递增子序列就是最长递增子序列。

方法思想:

为了求出该数组的最长递增子序列,就需要先求出在以数组中每个元素为结尾的情况下,最长的递增子序列是什么样的。因此首先要申请一块二维数组空间,存放以各个元素为结尾情况下的最长递增子序列。

首先显然可知,以0号元素为结尾的子序列只有0号元素自己。然后计算以1号元素为结尾的子序列,以此类推。

当计算n号的元素对应的子序列时,可以用n号元素与n-1号子序列的末尾元素比较,若n号元素大,则n号元素 暂时 求出的子序列就是n-1号元素对应子序列再加上n号元素。然后,将n号元素与n-2号元素对应子序列做同样对比,依次计算下去,选择一个可以使n号元素的子序列最长的情况。

按照上述方法,依次计算每个元素对应的结果之后的子序列,选择一个长度最长的序列即为整个数组的最长递增子序列。

按照同样的道理可以求出最长递减子序列。

举例说明上述思想:

对于序列A{35, 36, 39, 3, 15, 27, 6, 42}当处理到最后一个元素42时,以35, 36, 39, 3, 15, 27, 6为最末元素的最长递增序列分别为:

35

35,36

35,36,39

3

3,15

3,15,27

3,6

下面来计算42元素对应的子序列,首先将42与上述子序列末尾元素比较大小,小于42时,将42加入上述序列末尾,比较各个序列的长度,选择长度最长的,如下:

35,42

35,36,42

35,36,39,42,

3,42

3,15,42

3,15,27,42

3,6,42

这其中最长的递增序列为(35,36,39,42)和(3,15,27,42),所以序列A的最长递增子序列的长度为4,在A中长度为4的递增子序列不止一个。

则整个数组的最长递增子序列长度为4。

代码编写:

#include <iostream>
#include <vector>
using namespace std;

void lis(int a[], vector<int> *vt, int len){
for(int i = 0; i < len; i++){
vt[i].push_back(a[i]);
for(int j = i - 1; j >= 0; j--){
if(a[i] > vt[j].back() && vt[j].size() > (vt[i].size()-1)){
//选择长度最长的
vt[i] = vt[j];
vt[i].push_back(a[i]);
}
}
}
}

//求序列 35, 36, 39, 3, 15, 27, 6, 42 的最长递增子序列
int main(){
int len = 8;
int a[] = {35, 36, 39, 3, 15, 27, 6, 42};

vector<int> *vt = new vector<int>[len];
lis(a, vt, len);

for(int i = 0; i < len; i++){
for(int j = 0; j < vt[i].size(); j++){
cout<<vt[i][j]<<' ';
}
cout<<endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最长递增子序列