最长递增子序列

转自:http://blog.csdn.net/joylnwang/article/details/6766317

要求长度为i的序列的Ai{a1,a2,……,ai}最长递增子序列,需要先求出序列Ai-1{a1,a2,……,ai-1}中以各元素(a1,a2,……,ai-1)作为最大元素的最长递增序列,然后把所有这些递增序列与ai比较,如果某个长度为m序列的末尾元素aj(j<i)比ai要小,则将元素ai加入这个递增子序列,得到一个新的长度为m+1的新序列,否则其长度不变,将处理后的所有i个序列的长度进行比较,其中最长的序列就是所求的最长递增子序列。举例说明,对于序列A{35, 36, 39, 3, 15, 27, 6, 42}当处理到第九个元素(27)时,以35, 36, 39, 3, 15, 27, 6为最末元素的最长递增序列分别为
    35
    35,36
    35,36,39
    3
    3,15
    3,15,27
    3,6
当新加入第10个元素42时,这些序列变为
    35,42
    35,36,42
    35,36,39,42,
    3,42
    3,15,42
    3,15,27,42
    3,6,42

这其中最长的递增序列为(35,36,39,42)和(3,15,27,42),所以序列A的最长递增子序列的长度为4,同时在A中长度为4的递增子序列不止一个。

该算法的思想十分简单,如果要得出Ai序列的最长递增子序列,就需要计算出Ai-1的所有元素作为最大元素的最长递增序列,依次递推Ai-2,Ai-3,……,将此过程倒过来,即可得到递推算法,依次推出A1,A2,……,直到推出Ai为止,

代码如下
[cpp]  view plain  copy
  1. unsigned int LISS(const int array[], size_t length, int result[])  
  2. {  
  3.     unsigned int i, j, k, max;  
  4.   
  5.     //变长数组参数,C99新特性,用于记录当前各元素作为最大元素的最长递增序列长度  
  6.     unsigned int liss[length];  
  7.   
  8.     //前驱元素数组,记录当前以该元素作为最大元素的递增序列中该元素的前驱节点,用于打印序列用  
  9.     unsigned int pre[length];  
  10.   
  11.     for(i = 0; i < length; ++i)  
  12.     {  
  13.         liss[i] = 1;  
  14.         pre[i] = i;  
  15.     }  
  16.   
  17.     for(i = 1, max = 1, k = 0; i < length; ++i)  
  18.     {  
  19.         //找到以array[i]为最末元素的最长递增子序列  
  20.         for(j = 0; j < i; ++j)  
  21.         {  
  22.             //如果要求非递减子序列只需将array[j] < array[i]改成<=,  
  23.             //如果要求递减子序列只需改为>  
  24.             if(array[j] < array[i] && liss[j] + 1> liss[i])  
  25.             {  
  26.                 liss[i] = liss[j] + 1;  
  27.                 pre[i] = j;  
  28.   
  29.                 //得到当前最长递增子序列的长度,以及该子序列的最末元素的位置  
  30.                 if(max < liss[i])  
  31.                 {  
  32.                     max = liss[i];  
  33.                     k = i;  
  34.                 }  
  35.             }  
  36.         }  
  37.     }  
  38.   
  39.     //输出序列  
  40.     i = max - 1;  
  41.   
  42.     while(pre[k] != k)  
  43.     {  
  44.         result[i--] = array[k];  
  45.         k = pre[k];  
  46.     }  
  47.   
  48.     result[i] = array[k];  
  49.   
  50.     return max;  
  51. }  
该函数计算出长度为length的array的最长递增子序列的长度,作为返回值返回,实际序列保存在result数组中,该函数中使用到了C99变长数组参数特性(这个特性比较赞),不支持C99的同学们可以用malloc来申请函数里面的两个数组变量。函数的时间复杂度为O(nn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值