给定一个长度为N的数组,找出一个最长的单调递增子序列。
例如:给定数组A{5,6,7,1,2,8},则其最长的单调递增子序列为{5,6,7,8},长度为4。
一种思路是将其转换成LCS问题:将A数组排序后:A’{1, 2, 5, 6, 7, 8}
因为,原数组A的子序列顺序保持不变,而且排序后A’本身就是递增的,这样,就保证了两序列的最长公共子序列的递增特性。如此,若想求数组A的最长递增子序列,其实就是求数组A与它的排序数组A‘的最长公共子序列。
此外,本题可以直接使用动态规划求解。
算法如下:
设长度为N的数组为{a0,a1, a2, …an-1},则 假定以aj结尾的数组序列的最长递增子序列 长度为L(j),则L(j)={ max(L(i))+1, i
package other;
import java.lang.reflect.Array;
import util.ArrayUtil;
public class LongestIncreaseingSubSequence {
public static void main(String[] args) {
int[] a = new int[]{5,2,8,6,3,6,9,7};
System.out.println("最长递增子序列长度:"+longestIncreaseingSubSequence(a));
}
public static int longestIncreaseingSubSequence(int[] a){
int[] L = new int[a.length];
int[] S = new int[a.length];
int re = 0;
int rei= 0;
for (int i = 0; i < L.length; i++) {
//max 为a[0]到a[i]的最长公共子序列 并不定是最后返回值
int max = 1;
for (int j = i-1; j >=0; j--) {
int m = 1;
if(a[j]<a[i]&&max<L[j]+1){
max = L[j]+1;
S[i] = j;
}
}
L[i] = max;
if(re<L[i]){
re = L[i];
rei = i;
}
}
ArrayUtil.display("序列元素",a);
ArrayUtil.display("子序列长度",L);
ArrayUtil.display("前面的 数组序列号",S);
System.out.print("最长递增子序列为:");
display(a,S,rei);
System.out.println();
return re;
}
public static void display(int[] a,int[] S,int rei){
if(S[rei]!=0){
display(a,S,S[rei]);
}
System.out.print(a[rei]+" ");
}
}