最长递增子序列

//时间复杂度:O(nlogn)
#include<set>
#include<stack>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;

int Min(int *a, int len){
    int min = 0;
    for (int i = 0; i < len; i++)
        if (a[i] < min)
            min = a[i];
}

int LIS(int *a, int len){
    //存储对应递增序列长度的最大值的最小元素
    int *MaxV = new int[len + 1];
    MaxV[1] = a[0];//数组中的第一值,边界值
    MaxV[0] = Min(a, len) - 1;//数组中的最小边界值
    //存储对应索引的序列长度
    int *LISAry = new int[len];
    for (int i = 0; i < len; i++)
        LISAry[i] = 1;
    int nMaxILS = 1;//数组最长递增序列的长度
    for (int i = 1; i < len; i++){
        if (a[i] > MaxV[nMaxILS]){
            nMaxILS++;
            MaxV[nMaxILS] = a[i];
            LISAry[i] = nMaxILS;
        }
        else{
            int low = 1, height = nMaxILS;
            //利用二分法寻找从前向后第一个大于a[i]元素的索引
            while (low <= height){
                int mid = low + (height - low) / 2;
                if (a[i] >= MaxV[mid]){
                    low = mid + 1;
                }
                else{
                    height = mid - 1;
                }
            }
            LISAry[i] = low;
            //更新递增序列长度为low其最大元素改为更小的a[i]
            MaxV[low] = a[i];
        }
    }
    return nMaxILS;
}

int main(){
    int a[8] = { 1,-1,2,-3,4,-5,6,-7 };
    int len = sizeof(a) / sizeof(int);
    cout << LIS(a, len) << endl;
    return 0;
}

 

posted @ 2019-04-04 15:55  gzu_zb  阅读(270)  评论(0编辑  收藏  举报