Leetcode-300.Longest Increasing Subsequence

来源:互联网 发布:纸箱厂专业软件 编辑:程序博客网 时间:2024/06/06 10:43

//Problem description:
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.
Follow up: Could you improve it to O(n log n) time complexity?


Analysis:
Let’s say,
dp[i] means the longest increasing subsequence which ends at index i(nums[i] as its last element).
so the state equations are:

if dp[i] = max{dp[j]} + 1; j < i && nums[j] < nums[i];else dp[i] = 1;  if  no such j exists.

The result’s last element may not end at the last element.
It’s O(n^2) complexity
So we will have the following code:

int lengthOfLIS(vector<int>& nums) {    int n = nums.size();    vector<int>dp (n, 1);// initial to 1    int len = 0;    for (int i = 0; i < n; ++i)    {        for (int j = 0; j < i; ++j)        {            if (nums[j] < nums[i])                dp[i] = max(dp[j] + 1, dp[i]);         }        len = max(len, dp[i]);    }    return len; }

Here’s a faster solution

// O(nlogn) time int lengthOfLIS(vector<int>& nums) {    if (nums.empty()) return 0;    vector<int> ends{nums[0]};  //maintain the (SMALLEST) end element of each length of LIS     for (int num : nums)    {        if (num > ends.back()) ends.push_back(num);        else {            int l = 0, r = ends.size() - 1;            while(l < r){                int m = l + (r - l) / 2;                if(ends[m] < num) l = m + 1;                else r = m;             }                       ends[r] = num;        }    }     return ends.size();   }

Complete code for compute and print LIS:
Thanks :

#include <iostream>#include <string>#include <vector>using namespace std;class solution{public:    //computer the LIS and Print    vector<vector<int> > lengthOfLIS(vector<int>& nums)     {        int n = nums.size();        vector<int> dp(n, 1);// initial to 1        int maxlen = 0;        for (int i = 0; i < n; ++i)        {            for (int j = 0; j < i; ++j)            {                if (nums[j] < nums[i])                    dp[i] = max(dp[i], dp[j] + 1 );            }        maxlen = max(maxlen, dp[i]);        }        cout<< " maxlen : " << maxlen <<endl;        vector<vector<int> > res;        res = findLIS(nums, dp, maxlen);        return res;    }    vector<vector<int> > findLIS(vector<int>& nums, vector<int>& dp, int maxlen)    {        vector<vector<int> > res;        vector<int> v;        helper(nums, dp, res, v, maxlen, nums.size() - 1);        return res;    }    void helper(vector<int>& nums, vector<int>& dp, vector<vector<int> >& res, vector<int>& v, int maxlen, int last)    {        if (maxlen == 0)        {            reverse(v.begin(), v.end());            res.push_back(v);            reverse(v.begin(), v.end());// need reverse again            return;        }        for (int i = last; i >= 0; --i)        {            if (dp[i] == maxlen && ( v.empty() || nums[i] < v.back())){// v.empty() in the front            v.push_back(nums[i]);            helper(nums, dp, res, v, maxlen - 1, i - 1);            v.pop_back();//pop out the last element.        }        }    }};int main(int argc, char const *argv[]){    int num[] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};    vector<int> nums(num, num + sizeof(num) / sizeof(int));    solution s;    vector<vector<int> > res = s.lengthOfLIS(nums);     for (int i = 0; i < res.size(); i++) {         for (int j = 0; j < res[i].size(); j++)           cout<< res[i][j]<< " ";         cout<<endl;     }     return 0;}
0 0
原创粉丝点击