数组最长递增子序列

来源:互联网 发布:新手开淘宝店怎么装修 编辑:程序博客网 时间:2024/05/22 16:43

某道笔试题如下:

给出几组数据,如(20,30),(24,25),(30,40),(32,41),(x,y)中,x 代表身高,y代表体重。叠罗汉,下面的人要比上面的人身高低、体重小。问最多叠几层?


分析:此题目需要先按照”身高“数据排序(升序),然后求得排序后”体重“数据的最长递增子序列长度。

排序,可以采取二分法或者堆排序,时间复杂度不超过O(nlg(n))。 然后求”最长递增子序列长度“的高效代码如下(此题目也是《编程之美》2.16的一道题目):

时间复杂度:O(n) + o(nlog(n)),故时间复杂度是o(nlog(n))。

代码思路:可申请一个额外数组(空间换时间),其数组元素L[i],存放长度为i的递增序列,其最后元素的最小值

一开始,L[1] = 1,然后被更新为-1, 然后被更新为-3,-5,-7。注意理解最后元素的最小值。
之所以L[i]存放“长度为i的序列最后元素的最小值”,是一种“贪心”策略,这样方便下次遍历一个新元素时,如大于新数组的当前元素,则可以直接扩展到最长序列的后面。

int BinSearch(int * MaxV, int size, int x){    int left = 0, right = size-1;    while(left <= right)    {        int mid = (left + right) / 2;        if(MaxV[mid] <= x)        {            left = mid + 1;        }else        {            right = mid - 1;        }    }    return left;} int LIS(int * arr, int size){  int len;       int MaxV[size];    MaxV[0] = arr[0];  for(int i = 1; i < size; ++i)   {     if(arr[i] > MaxV[len-1])     {       MaxV[len++] = arr[i];     }   else     {       int pos = BinSearch(MaxV,len,arr[i]);       MaxV[pos] = arr[i];     }    }   return len;}


0 0
原创粉丝点击