Longest Increasing Subsequence

来源:互联网 发布:guava 并发编程 编辑:程序博客网 时间:2024/06/10 00:14

题目描述

找最大递增子序列,dp 时间复杂度 N2, 还可以优化到 NlogN, 不用dp的话非递归十分难解,时间复杂度 N的N次方。递归的话出口很难想。

思路

建立一个dp数组,dp[j]代表 以下 j为下标的最长递增子序列。那么对于 d[j] ,在数组中所有在它左边的下标,并且小于它的值的元素可以构成一个集合,这些集合中选一个递增子序列最大的出来,这个最大值+1,就是d[j]的值。

n^2void  GetDp(vector<int>&dp,vector<int>&v){    dp[0] = 1;    int size = v.size();    int max ;    for (int i = 1; i < size; ++i)    {        max = 0;        for (int j = 0; j < i; ++j)        {            if (v[j] < v[i]&&dp[j]>max)            {                max = dp[j];            }        }        dp[i] = max + 1;    }}int  lengthOfLIS(vector<int>&v){    if(v.size()==0)        return 0;    vector<int> dp(v.size());    vector<int> ret;    GetDp(dp,v);    int maxpos = 0;    for (int i = 1; i < dp.size(); ++i)    {        if (dp[i]>dp[maxpos])            maxpos = i;    }    if (maxpos == 0) //说明是逆序,每个dp值都为1,这个特殊情况返回第一个元素    {        ret.push_back(v[0]);    }    else    {        ret.push_back(v[maxpos]);    }    int pos = maxpos;    for (int i = maxpos-1; i >=0; --i)    {        if (dp[i] == dp[maxpos] - 1 && v[i] < v[maxpos])        {            ret.push_back(v[i]);            maxpos = i;        }    }    std::reverse(ret.begin(), ret.end());//因为保存到 ret 的值是反序的所以需要返回的时候置换回来*/    return ret;}
原创粉丝点击