方法一:
数组下标从0到arr_len-1,依次求每个元素的最长递增子序列,并保存在count_l数组中,最后根据count_l打印最长递增子序列数组。时间复杂度为O(n2),空间复杂度为O(n)
#include <stdio.h>
#define MAX_LEN 30
int count_l[MAX_LEN];
int lis;//记录最长子序列的长度
void display(int arr[], int index)
{
if(index < 0 || lis == 0)
{
return;
}
if(count_l[index] == lis)
{
lis--;
display(arr, --index);
printf("%d ", arr[index+1]);
}
else{
index--;
display(arr,index);
}
}
int main()
{
int arr[] = {1,2,-3,4,5,0,8};
int lis_index;
int arr_len;
arr_len = sizeof(arr)/sizeof(int);
int i, j;
for(i = 0; i < arr_len; i++)
{
count_l[i]=1;
for(j = 0; j < i; j++)
{
if(arr[i] > arr[j] && count_l[i] < count_l[j] + 1)
{
count_l[i] = count_l[j] + 1;
if(lis < count_l[i])
{
lis = count_l[i];
lis_index = i;
}
}
}
}
printf("the max len is %d\n", lis);
display(arr,lis_index);
while(1);
}
该方法是最容易想到的,在更新count_l[ i ]时,使用条件if(arr[i] > arr[j] && count_l[i] < count_l[j] + 1),减少了代码量。值得思考的是递归打印最长子序列,只能从后往前扫描,因为较大的数在后面,count_[ i ]==lis的,一定属于最长子序列,但由于要显示从小到大的数,所有printf语句在display()函数之后。