某道笔试题如下:
给出几组数据,如(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的递增序列,其最后元素的最小值。
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; }