数组最长递增子序列
来源:互联网 发布:翻页相册制作软件 编辑:程序博客网 时间:2024/05/01 21:12
求一维数组中的最长递增子序列,也就是着一个标号的序列 b[0],b[1],…,b[m] ( 0 <= b[0] < b[1] < … < b[m] < N ),使得 array[b[0]] < arrary[b[1]] < … < array[b[m]].
Sample思路
分析目标串:1,-1,2,-3,4,-5,6,-7。
使用i来表示当前遍历的位置:
当i=1,显然最长的递增序列为(1),序列长度为1。
当i=2,由于-1<1。因此需要丢弃第一个值重新建立串(-1),当前长度仍为1。
当i=3,由于2>1,2>-1。因此,最长序列为(1,2),(-1,2),长度为2。
依次类推之后,
假设在目标数组array[]的前i个元素中,最长递增子序列的长度为LIS[i]。那么,
LIS[i+1] = max{1,LIS[k]+1},array[i+1]>array[k],for any k<=i
即如果array[i+1]大于array[k],那么第i+1个元素可以接在LIS[k]长的子序列后面构成一个更长的子序列。
Optimize思路
前面的分析是,当考察第i+1个元素的时候,我们不考虑前面i个元素的分布情况。现在我们从另一个角度分析,在考察第i+1个元素的时候同时考虑前面i个元素的情况。
对于前面i个元素的任何一个递增子序列,如果这个子序列的最大元素比array[i+1]小,那么就可以将array[i+1]加在这个子序列后面,构成一个新的递增子序列。
比如当i=4的时候,目标序列为1,-1,2,-3,4,-5,6,-7最长递增子序列有(1,2),(-1,2)。那么只要4>2,就可以把4直接增加到前面的子序列。
因此,我们需要找到前i个元素中的一个递增子序列,使得这个递增子序列的最大元素比array[i+1]小,且长度尽量地长。
仍然假设在数组的前i个元素中,以array[i]为最大元素的最长递增子序列的长度为LIS[i]。
同时,假设:
长度为1的递增子序列最大元素的值为MaxV[1];
长度为2的递增子序列最大元素的值为MaxV[2];
……
长度为LIS[i]的递增子序列最大元素的值为MaxV[LIS[i]]。
#include <stdio.h>const int INF=100000000;int Max(int a,int b){ return a>b?a:b;}// O(N^2+N) = O(N^2)int LIS_Sample(int* array,int n){ int *LIS = new int[n]; //前i个元素中,最长递增子序列的长度为LIS[i] int Max_LIS = 1; for(int i=0;i<n;i++){ LIS[i] = 1; for(int j=0;j<i;j++){ //前面最长的序列 if(array[i] > array[j]) LIS[i] = Max(LIS[i],LIS[j]+1); } Max_LIS = Max(Max_LIS,LIS[i]); } delete LIS; return Max_LIS;}int LIS_Optimize(int* array,int n){ int *MaxV = new int[n+1]; //保存长度为i的递增子序列最大元素的值 int *LIS = new int[n]; //以array[i]为最大元素的最长递增子序列的长度为LIS[i] int Max_LIS = 1; //数组最长递增子序列的长度 MaxV[0] = -INF; MaxV[1] = array[0]; //初始化最长递增序列的信息; for(int i=0;i<n;i++) LIS[i] = 1; for(int i=1;i<n;i++){ //遍历历史最长递增序列信息 int j=0; for(int j = Max_LIS; j>=0;j--){ if(array[i] > MaxV[j]){ LIS[i] = j+1; break; } } //如果当前最长序列大于最长递增序列长度,更新最长信息 if(LIS[i] > Max_LIS){ Max_LIS = LIS[i]; MaxV[LIS[i]] = array[i]; } else if(MaxV[j]<array[i] && array[i] < MaxV[j+1]){ MaxV[j+1] = array[i]; } } /* //打印序列 stack<int> s; s.push(array[max_index]); int len = 1; int last = array[max_index]; for(int i=max_index-1;i>=0;i--){ if(LIS[i] == (Max_LIS-len) && array[i] < last) s.push(array[i]),len++; } while(!s.empty()){ printf("%d ",s.top()); s.pop(); } printf("\n"); */ return Max_LIS;}int main(){ int a[8] = {1,-1,2,-3,4,5,6,-7}; printf("Sample calculate the longest length is %d\n",LIS_Sample(a,8)); printf("Optimize calculate the longest length is %d\n",LIS_Optimize(a,8)); return 0;}
- 数组最长递增子序列
- 数组最长递增子序列
- 数组最长递增子序列
- 数组最长递增子序列
- 数组最长递增子序列
- 求数组中最长递增子序列
- 数组中最长递增子序列-java
- 求数组中最长递增子序列
- 数组中最长递增子序列
- 求数组中的最长递增子序列
- 求数组中最长递增子序列
- 求数组中最长递增子序列
- 数组中最长递增子序列
- 求数组中最长递增子序列
- 求数组中最长递增子序列
- 求数组中最长递增子序列
- 求数组中最长递增子序列
- 求数组中最长递增子序列
- 一天一算法之冒泡排序
- AutoHotKey的那些事儿:(四)、AutoHotkey的文件操作
- 第六周——贷款金额计算(数据类型转换)
- 异常空格,ASCII (194,160)问题
- Android开发笔记
- 数组最长递增子序列
- Git添加文件改动时出错
- 个人Android学习前言
- 【BeiJing2011】【BZOJ2462】矩阵模板
- web前端学习笔记02
- XCODE6 提交至 App Store
- 初识Mybatis-Spring
- OpenGL顶点数组
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦