/*************************************************************
* file:longest_incr_subsq.c
* brief:求数组的最长递增子序列(longest increasing subsequence)
* yejing@2015.2.7 1.0 creat
*************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>
int longest_incr_subsq(int array[], int len, int result[]){
if(!array || !len || !result)
return -1;
int i;
int tmp;
//最大长度
int current_max = 1;
//前驱节点向量
unsigned int* pre_vector = (int*)malloc(sizeof(int)*len);
//lis信息向量
unsigned int* lis_vector = (int*)malloc(sizeof(int)*len);
for(i = 1; i < len; ++i){
int j = 0;
tmp = current_max - 1;
//二分查找
while(tmp > j + 1){
int ave = (j + tmp)/2;
if(array[lis_vector[ave]] < array[i])
j = ave;
else
tmp = ave;
}
if(array[lis_vector[tmp]] < array[i])
j = tmp;
//对于小于lis_vector数组最小元素单独处理
if(!j){
if(array[lis_vector[j]] >= array[i]){
//update
lis_vector[j] = i;
continue;
}
}
if(j == current_max - 1){
if(array[lis_vector[j]] < array[i]){
pre_vector[i] = lis_vector[j];
lis_vector[current_max++] = i;
continue;
}
}
pre_vector[i] = lis_vector[j - 1];
lis_vector[j] = i;
}
i = current_max - 1;
tmp = lis_vector[current_max - 1];
while(pre_vector[tmp] != tmp){
result[i--] = array[tmp];
tmp = pre_vector[tmp];
}
result[i] = array[tmp];
free(pre_vector);
free(lis_vector);
pre_vector = NULL;
lis_vector = NULL;
return current_max;
}
int main(int argc, char* argv[]){
int i = 0;
int array[10] = {1, -1, 2, -2, 3, -3, -4, 5, 6, -4};
int result[10] = {0};
int lis_len = longest_incr_subsq(array, sizeof(array)/sizeof(int), result);
printf("lis is:");
for(i = 0; i < lis_len; i++)
printf("%d ", result[i]);
printf("\n");
return 1;
}