数组最长递增子序列

某道笔试题如下:

给出几组数据,如(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;
}


你可能感兴趣的:(数组最长递增子序列)