LeetCode: Longest Increasing Subsequence

来源:互联网 发布:js触发后台事件 编辑:程序博客网 时间:2024/06/18 09:49

题目:
Given an unsorted array of integers, find the length of longest increasing subsequence.

For example,
Given [10, 9, 2, 5, 3, 7, 101, 18],
The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length.

Your algorithm should run in O(n^2) complexity.

题目要求找出给定数组的最长递增子数列,子数列中相邻的数不一定要在原数列中也相邻,但要保证出现的顺序相同。如果用一般的方法做,时间复杂度达不到o(n^2)以内,这里使用动态规划来解这个问题。

解法一:
从前往后遍历整个数组,计算出以当前元素结尾的最长递增子序列的长度,用L[i]来表示,最后在L[i]中找出最大的值。状态转移方程:
L[i]=1+max{L[j], j=0,1,…,i-1}
由于找出以每个元素结尾的最长递增子序列的长度时需要遍历一遍之前的元素,所以整个算法的时间复杂度为o(n^2)。Accepted的代码:

class Solution {public:    int lengthOfLIS(vector<int>& nums) {        if(nums.size()==0) return 0;        vector<int> l;        l.push_back(1);        //遍历一遍数组,找出以第i个数结尾的最长递增子数列        for(int i=1;i<nums.size();i++)        {            l.push_back(1);            for(int j=0;j<i;j++)            {                if(nums[j]<nums[i]&&l[j]+1>l[i])                    l[i]=l[j]+1;            }        }        //在数组L中找出最长的递增子序列长度        int max_l=l[0];        for(int i=1;i<nums.size();i++)        {            if(l[i]>max_l) max_l=l[i];        }        return max_l;    }};

解法二:
其实,解法二是在解法一基础上的一种优化。在数列L[i]中,如果L[a]=L[b],而b>a的话,其实对L[b]的保存和遍历是没有意义的,因为对之后的某个元素c,如果c>b,那么c>a也一定成立。所以,基于这种情况,我们可以将L[b]从数组中剔除。建立一个数组B,B[i]用来保存最长递增子序列为长度为i+1时最后一个数的最小值,不断访问和更新B[i]即可。这样,问题就减少了很多不必要的重复遍历和判断,能减小时间复杂度,提高算法的效率。算法的时间复杂度在o(n)~o(n^2)之间。Accepted的代码:

class Solution {public:    int lengthOfLIS(vector<int>& nums) {        if(nums.size()==0) return 0;        vector<int> b;        b.push_back(nums[0]);        for(int i=1;i<nums.size();i++)        {            int longest=0;//表示当前元素作为最后一个元素时递增序列的长度-1            for(int j=0;j<b.size();j++)            {                if(nums[i]>b[j])                    longest=j+1;                if(longest<b.size())                {                    if(b[longest]>nums[i]) b[longest]=nums[i];                }                else                {                     b.push_back(nums[i]);                }            }        }        return b.size();    }};
0 0
原创粉丝点击