题解 | #最长上升子序列(一)#

最长上升子序列(一)

https://www.nowcoder.com/practice/5164f38b67f846fb8699e9352695cd2f

很对人讲了二分的过程,但没有讲为什么,我搜了一些用自己的话描述出来,有不恰当的地方请见谅。
新建一个 low 数组,low中的数组有序,且都是low数组最后数插入后目的数组最小值,这样才能发现最长的子序列。
例如:1 4 7 2 5 9 10 3 的最短子序列为 1 4 7 9 10 或 1 2 5 9 10 或 1 4 5 9 10,low数组就为1 2 3 9 10
更新过程如下:

    A[1] = 1,把1放进B[1],此时B[1] = 1,B[ ] = {1},len = 1

   A[2] = 4,把4放进B[2],此时B[2] = 4,B[ ] = {1,4},len = 2

   A[3] = 7,把7放进B[3],此时B[3] = 7,B[ ] = {1,4,7},len = 3

   A[4] = 2,因为2比4小,所以把B[2]中的4替换为2,此时B[ ] = {1,2,7},len = 3

   A[5] = 5,因为5比7小,所以把B[3]中的7替换为5,此时B[ ] = {1,2,5},len = 3

   A[6] = 9,把9放进B[4],此时B[4] = 9,B[ ] = {1,2,5,9},len = 4

   A[7] = 10,把10放进B[5],此时B[5] = 10,B[ ] = {1,2,5,9,10},len = 5

   A[8] = 3,因为3比5小,所以把B[3]中的5替换为3,此时B[ ] = {1,2,3,9,10},len = 5

C语言代码:

int Index(int *, int, int);

int LIS(int* arr, int arrLen ) {
    // write code here
    if(arrLen <= 1) return arrLen;
    int low[arrLen];
    low[0] = arr[0];
    int len = 1;
    for(int il = 0, ia = 1; ia != arrLen;ia++){
        if(low[il] < arr[ia]){
            low[++il] = arr[ia];
            len++;
        }else{
            int index = Index(low, il, arr[ia]);
            low[index] = arr[ia];
        }
    }
    return len;
}

int Index(int *arr, int il, int target){
    int lo = 0, hi = il;
    while(lo < hi){
        int mid = lo + (hi - lo)/2;
        if(arr[mid] >= target){
            hi = mid;
        }else{
            lo = mid + 1;
        }
    }
    return lo;
}
全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务