LeetCode300. 最长上升子序列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Jaster_wisdom/article/details/81943937

给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4 
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4

说明:

  • 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
  • 你算法的时间复杂度应该为 O(n2) 。

题目分析:

方法一:动态规划,用dp[i]表示以nums[i]结尾的最长上升子序列。那么如何求dp[i]呢,只要看nums[i]之前的元素,哪个元素比nums[i]要小,并且它的dp[]值最大,那么dp[i]就在它dp值的基础上加1即可。最后求所有dp数组的最大值。

代码展示:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> dp(nums.size(),1);
        if(nums.size()==0)
            return 0;
        int ans = 1;
        for(int i=1;i<nums.size();i++){
            int maxDp = 0;
            for(int j=0;j<i;j++){
                if(nums[j]<nums[i])
                    maxDp = max(maxDp,dp[j]);
            }
            dp[i] = maxDp + 1;
            ans = max(ans,dp[i]);
        }
        return ans;
    }
};

方法二:首先将第一个元素存入vec数组,然后依次看后面的元素。若后面的元素大于vec数组的最后一个元素,则将其加入到vec末尾,否则将它替换掉vec数组中第一个大于等于它的元素。最后返回vec的大小即可。

例如说,原数组:[10,9,2,5,3,7,101,18]

1. 将10加入到vec数组中,vec[] = [10]

2.9<10, 用9替换掉数组中大于等于9的元素,vec[] = [9]

3. vec[] = [2]

4.vec[] = [2,5]

5.vec[] = [2,3]

6.vec[] = [2,3,7]

7.vec[] = [2,3,7,101]

8.vec[] = [2,3,7,18]

返回vec的数组个数4

代码展示:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> vec;
        if(nums.size()==0)
            return 0;
        vec.push_back(nums[0]);
        for(int i=1;i<nums.size();i++){
            if(nums[i]>vec.back())
                vec.push_back(nums[i]);
            else{
                for(int j=0;j<vec.size();j++){
                    if(vec[j]>=nums[i]){
                        vec[j] = nums[i];
                        break;
                   }
                }
                //*lower_bound(vec.begin(),vec.end(),nums[i]) = nums[i];
            }
        }
        return vec.size();
    }
};

说明:代码12-17行可以用第18行代码代替,作用是相同的。函数lower_bound(first,second,val)在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。

 

阅读更多
换一批

没有更多推荐了,返回首页