[leetcode] 300. Longest Increasing Subsequence

题目:
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(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?
题意:
给定一个无数的数组,找出最长的递增子序列。
思路:
这道题目是一道典型的题目,算法必练。使用的是动态规划的思路,有两种解法,一个是时间复杂度是O(n^2)的解法,一个是降到O(n*lg(n))的解法。以下分别讨论两种思路。
O(n^2)的 解法:
首先是基本思路,因为考虑的是最长递增子序列,所以我们可以保存第i歌元素之前出现的长度为1的子序列,长度为2的子序列,等等。当考虑当前第i歌元素时我们只需要决定以第i歌元素为结尾的子序列的长度是多大,那么找出前面最长的一个子序列,这个子序列满足的条件是最后一个元素要比当前第i歌元素要小,那么第i歌元素就可以接到这个序列上面从而变长。所以我们保存一个数组来记录,从第1个元素到第i歌元素之间,长度为1,2..i-1的长度的子序列的结尾元素,比如找出第i歌元素只可以接在长度为k的子序列后面,那么接上i之后长度就变成了k+1,那么我们这个时候把k+1长度的子序列的结尾元素变成nums[i]。所以依次扫描nums中的n歌元素时,会顺序遍历一遍各个长度的子序列的结尾,所以最终复杂度是O(n^2)。
接下来考虑O(n*lg(n))的算法:
观察前面的分析我们发现,其实k个长度的子序列的最后一个元素一定是小于k+1个长度的子序列的最后一个元素。所以我们只需要二分查找前面的元素就可以了。
代码如下:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int size = nums.size();
        if(size <= 1)return size;
        vector<int> increase_sequence;
        for(auto i = 0; i < size; i++) {
            auto res = lower_bound(increase_sequence.begin(), increase_sequence.end(), nums[i]);
            if(res == increase_sequence.end())increase_sequence.push_back(nums[i]);
            else increase_sequence[res - increase_sequence.begin()] = nums[i];
        }
        return increase_sequence.size();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值