最大上升子序列(不连续)

O(n²)算法:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n=nums.size();
        if(n==0){
            return 0;
        }
        else{
            int m[n]={1};
            for(int i=1;ifor(int j=0;j//如果i的左边存在j使得nums[j]
                    if(nums[j]1>m[i]){
                        m[i]=m[j]+1;
                    }
                }
            }
            int max=0;
            for(int i=0;iif(m[i]>max){
                    max=m[i];
                }
            }
            return max;
        }

    }
};

O(nlogn)算法:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n=nums.size();
        if(n==0){
            return 0;
        }
        else{
            int g[n+1];
            for(int i=1;i<=n;i++){
                g[i]=10000001;
            }
            int d[n]={1};
            for(int i=0;iint k=lower_bound(g+1,g+n+1,nums[i])-g;
                d[i]=k;
                g[k]=nums[i];
            }
            int max=0;
            for(int i=0;iif(d[i]>max){
                    max=d[i];
                }
            }
            return max;
        }
    }
};

因为是在Leetcode上做的,就按照它的格式

O(nlogn)的注释版本,希望过几天还能看懂/(ㄒoㄒ)/~~
代码:

#include 
#include 
using namespace std;
const int INF=10000001;
const int maxn=101;
int dp[maxn];
int g[maxn];
int lis(int* a,int n){
    //g[i]表示的是最长子序列长度为i的情况(dp[i])的最小状态编号(即最前的数字!!(不是位置)),因为同样的长度,最前的肯定更有优势
    for(int i=1;i<=n;i++){
        g[i]=INF;
    }
    for(int i=0;i//g数组中大于等于a[i]的最小位置(i),即最大子序列长度
        //g[1]<=g[2]<=g[3]<=...<=g[n]
        //减去g而不是减去g+1保证第一次循环得到的也是1,因为这个值是赋给dp,也就是代表最大子序列长度
        //这里lower_bound可以求最大上升子序列,而upper_bound可以求最大不下降子序列,重点记住
        int k=lower_bound(g+1,g+n,a[i])-g;
        //比如第四次循环,访问的元素是4,所以就在g数组{1,2,10}中查找比4大的最小值(10),找到的这个位置也就是4应该放在g数组中的位置
        //也即是4的最大子序列长度,因为前面有1,2比4小
        //将以i位置(和g的i不同)结尾的最大子序列长度更新
        dp[i]=k;
        g[k]=a[i];
        printf("dp[%d]=%d g[%d]=%d\n",i,dp[i],k,g[k]);
        printf("以第%d个元素结束的最大子序列长度为%d 最大子序列长度为%d的最前的元素是%d\n",i,dp[i],k,g[k]);
    }
}
int main(void){
    int a[10]={2,3,10,4,5,1,3,6,9,7};
    int max=lis(a,10);
    printf("原数列: ");
    for(int i=0;i<10;i++){
        printf("%d ",a[i]);
    }
    printf("\ndp数组: ");
    for(int i=0;i<10;i++){
        printf("%d ",dp[i]);
    }
    printf("\ng数组: ");
    for(int i=0;i<10;i++){
        printf("%d ",g[i]);
    }
    printf("\n");
    printf("%d\n",max);
    return 0;
}

你可能感兴趣的:(杂七杂八)