300. Longest Increasing Subsequence

来源:互联网 发布:深夜解莫软件 编辑:程序博客网 时间:2024/06/14 05:44

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?

s思路:
1. 这题之前做过,印象深刻,以至于不能好好的思考,记忆瞬间占领大脑,大脑立马停摆,不能认真思考和看清眼前的题目了!
2. 先看o(n^2)的做法:由于是求最长,就想到了dp,而最长又是从元问题一个一个的比较得到的,所以问题又可以分解,因此更加确定用dp了。
3. 题目要求降低复杂度到o(nlgn)。好好观察发现,在做dp的时候,有很多重复,例如:当判断101的位置的最长时,如果知道此时前面最长序列为[2,3,7]那么就没有必要从头到尾一个一个的尝试,完全可以用binary search找到101的位置,如果101的位置大于最后一个位置,就+1,如果小于最后一个值,则把对应的值给修改了,长度不变,那么就免去了一个一个尝试的啰嗦,变o(n)->o(lgn)
这里写图片描述
4. 这道题妙的地方在于,用维护的最长的序列的长度作为返回值,不用专门去找这个长度,而是找出一个这样的序列,虽然最后返回的这个序列不一定是最长序列,但是其长度确实是最长的!

//方法1:dp.复杂度o(n^2)class Solution {public:    int lengthOfLIS(vector<int>& nums) {        int n=nums.size();        if(n==0) return 0;        vector<int> dp(n,1);        int mxlen=1;        for(int i=1;i<n;i++){            for(int j=0;j<i;j++){                int cur=nums[i]>nums[j]?dp[j]+1:1;                dp[i]=max(dp[i],cur);            }                mxlen=max(mxlen,dp[i]);        }        return mxlen;    }};//方法2:binary searchclass Solution {public:    int lengthOfLIS(vector<int>& nums) {        int n=nums.size();        if(n==0) return 0;        vector<int> res;        for(int i=0;i<n;i++){            auto it=lower_bound(res.begin(),res.end(),nums[i]);//bug:改用lower_bound,不能upper_bound            //因为lower_bound是大于和等于val的第一个位置;upper_bound是大于val的第一个位置!            if(it!=res.end()){                res[it-res.begin()]=nums[i];                    }else{                res.push_back(nums[i]);                }        }        return res.size();    }};
0 0
原创粉丝点击