lintcode--最长上升子序列

来源:互联网 发布:黑马程序员有公司要么 编辑:程序博客网 时间:2024/05/22 11:25

题目描述:
给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度。

说明:
最长上升子序列的定义:
最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的。
https://en.wikipedia.org/wiki/Longest_increasing_subsequence

样例
给出 [5,4,1,2,3],LIS 是 [1,2,3],返回 3
给出 [4,2,4,5,3,7],LIS 是 [2,4,5,7],返回 4

思路讲解:
第一种时间复杂度为o(nlog(n))
由于我们这道题要的只是子序列的个数,所以我们用一个临时数组res存储子序列,首先将第一个数放进去,然后对原数组的每一个数进行循环,如果这个数比res数组的最后一个数大,就将其直接加到res数组中,反之,在res数组中,找到一个属于这个数的位置,然后将其放入,用新数去更新前面的元素。虽然其会导致子序列的更新,但是其并不会影响子序列的长度。
例如:[4,2,4,5,3,7],
res数组变化过程:4->2->2,4->2,4,5->2,3,5->2,3,5,7

第二种时间复杂度为o(n*n)
首先需要一个临时数组res,其长度与原数组等长,首先我们将其都置为1,然后从第二个开始如果其大于前面的某一个数,那么其res中的值就为那个数所对应的res的值加1,一直这样就可以将其全部算出,后面我们只需要将res数组中的最大值找出来即可。
例如:[4,2,4,5,3,7]
res数组变化为[1,1,1,1,1,1] -> [1,1,1,1,1,1] -> [1,1,2,1,1,1] -> [1,1,2,3,1,1]->[1,1,2,3,2,1] -> [1,1,2,3,2,4]

代码详解:

第一种时间复杂度o(nlog(n))的代码

class Solution {public:    /*     * @param nums: An integer array     * @return: The length of LIS (longest increasing subsequence)     */    int longestIncreasingSubsequence(vector<int> &nums) {        // write your code here        if(nums.size()==0)        {            return 0;        }        int res[100];        int length=0;        res[0]=nums[0];        for(int i=1;i<nums.size();i++)        {            if(nums[i]>res[length]){                length++;                res[length]=nums[i];            }            else{                int pos=binary_search(res,nums[i],length);                res[pos]=nums[i];            }        }        return length+1;    }    int binary_search(int *res,int num,int length)    {        int left,right,mid;        left=0;        right=length;        while(left<right){            mid=left+(right-left)/2;            if(res[mid]>=num){                right=mid;            }            else{                left=mid+1;            }        }        return left;    }};

第二种时间复杂度为o(n*n)

class Solution {public:    /*     * @param nums: An integer array     * @return: The length of LIS (longest increasing subsequence)     */    int longestIncreasingSubsequence(vector<int> &nums) {        // write your code here        if(nums.size()==0)        {            return 0;        }        int res[100];        for(int i=0;i<nums.size();i++)        {            res[i]=1;            for(int j=0;j<i;j++)            {                if(nums[j]<nums[i]&&res[j]+1>res[i]){                    res[i]=res[j]+1;                }            }        }        int max=0;        for(int i=0;i<nums.size();i++)        {            if(max<res[i]){                max=res[i];            }        }        return max;    }};
原创粉丝点击