最长递增子序列(longest increasing subsequence)

来源:互联网 发布:midas有限元分析软件 编辑:程序博客网 时间:2024/06/04 17:59

问题

给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8},长度为4.

int LIS(int nums[], int n, int result[]){//暴力法,时间O(n^2)int* lis = new int[n];int* pre = new int[n];int maxlen = 1, maxIndex = 0;lis[0] = 1;memset(pre, -1, n * sizeof(int));//此处不能用sizeof(pre),这是因为pre是指针,sizeof(pre)为4,并非数组的大小。for(int i = 1; i < n; i++){lis[i] = 1;//将int型的lis数组全初始化为1,不能用memset(lis, 1, n * sizeof(int)),这样赋值会使初值为00000001_00000001_00000001_00000001,为16843009。//memset是按字节赋值,因此只能全部赋值为0, 或者全部是f,即-1。for(int j = 0; j < i; j++)if(nums[i] > nums[j] && (lis[j] + 1) > lis[i]){lis[i] = lis[j] + 1;pre[i] = j;}if(lis[i] > maxlen){maxlen = lis[i];maxIndex =  i;}}int i = maxlen - 1;while(maxIndex != -1){result[i--] = nums[maxIndex];maxIndex = pre[maxIndex];}delete [] lis, delete [] pre;return maxlen;}int LIS2(int nums[], int n, int result[]){//采用二分查找,时间复杂度O(nlogn)int maxlen = 1, maxIndex = 0;int* maxNums = new int[n];//构建maxNums数组,其中maxNums[i]存储的是所有长度为i+1的最长递增子序列的最后一个元素的最小值int* index = new int[n];//index数组记录maxNums数组中对应元素在原nums数组中的秩int* pre = new int[n];//pre数组记录nums数组中每一元素的前驱的秩memset(pre, -1, n * sizeof(int));memset(index, 0, n * sizeof(int));maxNums[0] = nums[0];for(int i = 1; i < n; i++){//利用二分查找,在maxNums数组中查找nums[i]int lo = 0, hi = maxlen;while(lo < hi){int mi = (lo + hi) >> 1;if(maxNums[mi] < nums[i])lo = mi + 1;else hi = mi;}//求出的lo为大于nums[i]的元素的最小秩。参考数据结构(C++第3版)P56if(lo == maxlen){//在maxNums中未找到nums[i],说明nums[i]大于maxNums中的最大值,则将此值插入maxNums中,maxlen长度加一。maxNums[maxlen] = nums[i];index[maxlen] = i;pre[i] = index[maxlen - 1];//当前元素的前驱的秩即为长度为maxlen - 1的最长递增子序列的最后一个元素的秩maxlen++;maxIndex = i;}else{maxNums[lo] = nums[i];//在maxNums中找到了nums[i],说明nums[i]小于原来位置的值,直接将原来位置的值替换index[lo] = i;pre[i] = (lo == 0) ? -1 : index[lo - 1];//当前元素的前驱的秩即为长度为lo - 1的最长递增子序列的最后一个元素的秩}}int j = maxlen - 1;while(maxIndex != -1){result[j--] = nums[maxIndex];maxIndex = pre[maxIndex];}delete [] maxNums, delete [] pre, delete [] index;return maxlen;}


0 0
原创粉丝点击