如:1,-1,2,-3,4,-5,6,-7中,最長遞增子序列是1,2,4,6.數組
【解法1】spa
假設在目標數組array[]的前i個元素中,最長遞增子序列的長度爲LIS[I],code
那麼對於任意k<=i,當array[i+1]>array[k]時,LIS[i+1]=LIS[K]+1,不然LIS[i+1]=1。blog
此法特色:在考慮第i+1個元素的時候不考慮前面i個元素的狀況。class
代碼:di
int longestSub(int a[], int n) { int *LIS=new int[n]; int max=0; for(int i=0; i<n; i++){ LIS[i]=1; for(int j=0; j<i; j++) if(a[i]>a[j]&&LIS[j]+1>LIS[i]) LIS[i]=LIS[j]+1; if(max<LIS[i]) max=LIS[i]; } delete [] LIS; return max; }
【解法2】co
對於前面i個元素的任何一個遞增子序列,若是這個子序列的最大元素比array[i+1]小,那麼就能夠將array[i+1]加在這個子序列後面,構成一個新的遞增子序列。let
所以,要找到前i個元素中的一個遞增子序列,使得這個遞增子序列的最大的元素比array[i+1]小,且長度儘可能長。這樣即可找到以array[i+1]爲最大元素的最長遞增子序列。new
假設:return
在數組前i個元素中,以array[i]爲最大元素的最長遞增子序列的長度爲LIS[i]。
長度爲i的遞增子序列最大元素的最小值爲maxV[i]。。。
代碼:
int LIS(int a[], int n) { int *maxV=new int[n+1]; int *LIS=new int[n]; int amin=a[0]; for(int i=0; i<n; i++) if (amin>a[i]) amin=a[i]; maxV[1]=a[0]; maxV[0]=amin-1;//邊界值 for(int i=0; i<n; i++) LIS[i]=1; int nMaxLIS=1;//最長子序列長度 for(int i=1; i<n; i++) { int j; for(j=nMaxLIS; j>=0; j--) //for(j=LIS[i-1]; j>-1; j--) { if(a[i]>maxV[j]) { LIS[i]=j+1; break; } } if(LIS[i]>nMaxLIS){ nMaxLIS=LIS[i]; maxV[LIS[i]]=a[i]; } else if(maxV[j]<a[i]&& a[i]<maxV[j+1]){ maxV[j+1]=a[i];//更新最大元素最小值 } } return nMaxLIS; }