【LeetCode】300. Longest Increasing Subsequence

来源:互联网 发布:oppo手机root软件 编辑:程序博客网 时间:2024/06/06 09:56

题目:

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?

分析:
这道题要求数组中最长的递增序列的长度。有两种做法。

第一种:设dp[i]记录以nums[i]结尾的递增序列的大小,遍历一遍数组nums,通过比较num[i]与nums[j]的大小(j<i),再根据dp[j]的值来更新dp[i]的值。最后数组dp中值最大的元素就是我们要求的最大长度。这种做法的时间复杂度为O(n*n).

代码:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int sum = 0;
        int *dp = new int[nums.size()];
        dp[0] = 1;
        for(int i = 1;i<nums.size();i++)
        {
            dp[i] = 1;
            for(int j = i-1;j>=0;j--)
            {
                if(nums[j]<nums[i])
                {
                    if(dp[i]<dp[j]+1)
                    dp[i] = dp[j]+1;
                }
                else if(dp[j] == 1)
                break;
            }
        }
        for(int i = 0;i<nums.size();i++)
        {
            if(sum<dp[i])
            sum = dp[i];
        }
        return sum;
    }
};

第二种:设一个数组pos,pos[i]记录长度为i+1的序列的最后一个数,设变量sum记录当前序列的最大长度。遍历数组nums,有以下几种情况:
(1)nums[i]小于pos[0],即nums[i]小于长度为1的序列的最后一个数,更新pos[0]的值

(2)nums[i]大于pos[sum],即nums[i]大于长度最长的序列的最后一个数,可构成一个更长的序列,将sum+1,然后更新pos[sum]的值。

(3)nums[i]在中间,通过二分搜索找到在数组pos中第一个大于nums[i]的位置temp,然后更新pos[temp]的值。

最后sum+1就是我们要求的最大长度。这种做法的时间复杂度为O(nlogn).

代码:

int bsearch(vector<int> pos,int start,int end,int target)
{
    while(start <= end){
        int mid = (end + start) / 2;
        if(pos[mid] == target){
            return mid;
        }
        if(pos[mid] < target){
            start = mid + 1;
        }
        if(pos[mid] > target){
            end = mid - 1;
        }
    }
        return start;
}
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
     if(nums.size()==0)
     return 0;
     int sum = 0;
     vector<int> pos;
     for(int i = 0;i<nums.size();i++)
     pos.push_back(0);
     pos[0] = nums[0];
     for(int i = 1;i<nums.size();i++)
     {
         if(nums[i]<=pos[0])
         {
          
             pos[0] = nums[i];
         }
         else if(nums[i]>pos[sum])
         {
             sum++;
             pos[sum] = nums[i];
         }
         else
         {
            int temp = bsearch(pos,0,sum,nums[i]);
            pos[temp] = nums[i];
           
         }
     }
     return sum+1;
    }
};


0 0
原创粉丝点击