最长递增子序列

2014-11-23 21:55:41 · 作者: · 浏览: 11

问题描述

找出一个数组中的最长递增子序列LIS(不一定连续,但顺序不能乱),如数组arr={5, 6, 7, 1, 2, 8},其最长递增子序列 为{5,6,7,8},长度为4。

四种解法

直接法

遍历数组找出从arr[i]开始的最长递增子序列,复杂度为O(n^2)
int lis1(int arr[],int n)
{
	int result=0;
	int curMax,tmp;
	for(int i=0;i
  
   =tmp)
			{
				curMax++;
				tmp=arr[j];
			}
		}
		if(curMax>result)
				result=curMax;
	}
	return result;

}
  

动态规划

设以arr[i]结尾的最长递增子序列的长度为L[i],则L[j]={ max(L(i))+1, i int lis2(int arr[], int len) { cout< arr[i] && longest[j]


    int lis3(int *array, int n) //计算最长递增子序列的长度,计算B数组的元素,array[]循环完一遍后,B的长度len即为所求 { int *B=new int[n]; int len = 1; //B的初始长度 B[0] = array[0]; int i, pos = 0; for(i=1; i
    
      B[len-1]) //如果大于B中最大的元素,则直接插入到B数组末尾 { B[len] = array[i]; ++len; } else { pos = BiSearch(B, len, array[i]); //二分查找需要插入的位置 B[pos] = array[i]; //修改B[pos],这里是修改不想一般的做插入操作 } } return len; } //修改的二分查找算法,返回数组元素需要插入的位置。 int BiSearch(int *b, int len, int w) { int left = 0, right = len - 1; int mid; while (left <= right) { mid = left + (right-left)/2; if (b[mid] > w) right = mid - 1; else if (b[mid] < w) left = mid + 1; else //找到了该元素,则直接返回 return mid; } return left;//数组b中不存在该元素,则返回该元素应该插入的位置 }