300. Longest Increasing Subsequence

来源:互联网 发布:日系护肤品知乎 编辑:程序博客网 时间:2024/05/17 22:08

题目:Longest Increasing Subsequence

原题链接:https://leetcode.com/problems/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(n * n) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

给出一个未排序的整数序列,返回其中最长上升子序列(LIS)的长度。
例:[10, 9, 2, 5, 3, 7, 101, 18]
那么LIS为[2, 3, 7, 101],所以长度为4.
注意:算法要求时间复杂度为O(n * n) ,如果能做到O(n log n)更好。

O(n * n)复杂度的解决方法:
设数组的长度为len,设dp[ len ],dp[ i ]表示以nums[ i ]结尾的最长子序列的长度,初始都设为1。
那么dp[ 0 ] = 1,对于其他任意dp[ i ],dp[ i ]的值为dp[ 0 … i - 1 ]中所有结尾值小于nums[ i ]的最大dp值加1。即如果nums[ i ] > nums[ j ] , 则令dp[ i ] = max( dp[ j ] + 1, dp[ i ] ),扫描数组结束然后返回最大的dp值即可。
代码如下:

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

O(n log n)复杂度的解决方法:
设一个数组ans,ans的长度表示遍历到当前元素为止的LIS的长度。
扫描nums,每到一个元素num,在ans中寻找不小于num的第一个元素,如果没有寻找到,则往ans中插入这个元素,如果找到了,则把这个元素替换成num。
以样例[10, 9, 2, 5, 3, 7, 101, 18]为例,模拟每一次遍历的结果:

当前遍历元素 ans中的元素 ans的长度 10 10 1 9 9 1 2 2 1 5 2,5 2 3 2,3 2 7 2,3,7 3 101 2,3,7,101 4 18 2,3,7,18 4

注意,虽然长度是LIS的长度,但是ans序列中的元素却并不能保证一定就是LIS,只能保证最后一个元素是LIS中的最后一个元素。

代码如下:

class Solution {public:    int lengthOfLIS(vector<int>& nums) {        vector<int> ans;        for(int num : nums) {            auto it = lower_bound(ans.begin(), ans.end(), num);            if(it == ans.end()) ans.push_back(num);            else *it = num;        }        return ans.size();    }};
0 0