Method One:
Using the LCS method, computes the longest common subsequence between sequence A and the sorted sequence B. In this case, a quick sort is used, and then the LCS method is used.
voidQuiksort (intA[],intStartintend) { inttemp=A[start]; inti=start,j=end; if(i<j) { while(i<j) { while(i<j&&a[j]>temp) J--; A[i]=A[j]; while(i<j&&a[i]<temp) I++; A[J]=A[i]; } A[j]=temp; Quiksort (A,start,i-1); Quiksort (A,i+1, end); }}intLCS (intA[],intB[],intLen) {Vector<int> F (len+1,0); for(intI=1; i<=len;i++) for(intj=1; j<=len;j++) {F[j]=a[i-1]==b[j-1]?f[j-1]+1: Max (f[j],f[j-1]); } returnF[len];}
Method Two:
Dynamic programming, with F[i] represents the maximum length of an incrementing subsequence ending with a[i]. So
F[i]=max (F[j]) +1, wherein A[j]<a[i]&&j<i, J takes all values between 0~i, and finally asks for the maximum value of all F[i]; the time complexity of the method is O (N2)
intdpintA[],intLen) {Vector<int> f (Len,1); for(intI=1; i<len;i++) { for(intj=0; j<i;j++) F[i]=a[j]<a[i]?max (f[i],f[j]+1): F[i]; } intresult=1; for(intI=0; i<len;i++) Result=Max (result,f[i]); returnresult;}
Method Three:
Defines an F (n) to store the minimum end of the corresponding length of LIS. As f (0) stores the minimum end of the LIS with a length of 1, f (1) stores the minimum end of the LIS with a length of 2.
For example, the sequence A[9]={2,1,5,3,6,4,8,9,7},len records the length of the F sequence.
First F[0]=a[0]=2,len=1;
Then insert a[1] into the F sequence,a[1]< f[0], so f[0]=a[1]=1; Len is still 1;
Then insert a[2] into the F sequence,a[2]> f[0], so f[1]=a[2]=5; len=2;
Insert a[3] into the F sequence,a[3]< f[1], so a[3] is inserted into the f[1] position. F[1]=a[3]=3;len or 2?
Insert a[4] into the F sequence,a[4]> f[1], so a[4] is inserted into the f[2] position. f[2]=a[4]=6; The length of the f sequence becomes longer, Len is 3.
Insert a[5] into the F sequence,a[5]< f[2], so a[5] is inserted into the f[2] position. F[2]=a[5]=4;len or 3?
Insert a[6] into the F sequence,a[6]> f[2], so a[6] is inserted into the f[3] position. f[3]=a[6]=8; The length of the f sequence becomes longer, Len is 4.
Insert a[7] into the F sequence,a[7]> f[3], so a[7] is inserted into the f[4] position. f[4]=a[7]=9; The length of the f sequence becomes longer, Len is 5.
Insert a[8] into the F sequence,a[8]< f[4], so a[8] is inserted into the f[3] position. F[3]=a[8]=7;len or 5?
Here we use a binary lookup method to find out where each a[i] should be inserted into the F sequence. If A[i] is greater than the last element of the F sequence at this time, then only the a[i] is inserted at the end of the sequence F, otherwise the binary lookup method is used to insert a[i]; F[i] Stores the value of the minimum end of an incrementing subsequence of length i+1. The time complexity of this method is O (NLOGN)
intBfind (vector<int> A,intLenintnum) { intstart=0; intend=len-1; while(start<=end) { intMid= (start+end)/2; if(a[mid]==num)returnmid; Else if(a[mid]>num) End=mid-1; ElseStart=mid+1; } returnstart;}intNlogn (intA[],intN) {Vector<int>f (n); f[0]=a[0]; intlen=1; for(intI=1; i<n;i++) { if(f[len-1]<A[i]) {F[len]=A[i]; Len++; } Else { intpos=bfind (F,len,a[i]); F[pos]=A[i]; } } returnLen;}
The test implementation code for the above three methods is as follows:
Where the main function len1 output is the result of method one;
Len2 output is the result of method two;
Len3 output is the result of method three;
#include <iostream> #include <vector>using namespace std;void quiksort (int a[],int start,int end) {int temp=a [Start];int i=start,j=end;if (I<j) {while (i<j) {while (i<j&&a[j]>temp) J--;a[i]=a[j];while (i< j&&a[i]<temp) i++;a[j]=a[i];} A[j]=temp;quiksort (a,start,i-1); Quiksort (a,i+1,end);}} int LCS (int a[],int b[],int len) {vector<int> f (len+1,0); for (int. i=1;i<=len;i++) for (int j=1;j<=len;j++) {f[ J]=a[i-1]==b[j-1]?f[j-1]+1:max (F[j],f[j-1]);} return F[len];} int dp (int a[],int len) {vector<int> f (len,1); for (int. i=1;i<len;i++) {for (int j=0;j<i;j++) f[i]=a[j]<a[i ]?max (f[i],f[j]+1): F[i];} int result=1;for (int i=0;i<len;i++) Result=max (Result,f[i]); return result;} int bfind (vector<int> a,int len,int num) {int start=0;int end=len-1;while (start<=end) {int mid= (start+end)/2; if (a[mid]==num) return Mid;else if (a[mid]>num) end=mid-1;elsestart=mid+1;} return start;} int Nlogn (int a[],int n) {vector<int> f (n); f[0]=a[0];int len=1;for (int i=1; i<n;i++) {if (F[len-1]<a[i]) {f[len]=a[i];len++;} Else{int Pos=bfind (F,len,a[i]); f[pos]=a[i];}} return Len;} int main () {int a[9]={2,1,5,3,6,4,8,9,7};int b[9];for (int i=0;i<9;i++) {b[i]=a[i];} Quiksort (a,0,8); int Len=lcs (a,b,9); Cout<<len<<endl;int LEN2=DP (b,9); cout<<len2<<endl;int Len3=nlogn (b,9); Cout<<len3<<endl;}
Maximum Increment sub-sequence