您的位置:首页 > 产品设计 > UI/UE

【Leetcode】Longest Increasing Subsequence

2016-05-21 22:19 501 查看
题目链接: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(n2) complexity.

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

思路:

1、简单动态规划,c[i]表示从0~i的数组中 包含nums[i]的LIS,状态转移方程:c[i]=max{c[j]+1} ,j<i且nums[i]>nums[j],时间复杂度为O(n^2)

2、动态规划加二分搜索,b[i]表示长度为i的LIS最后一个元素大小,end是b数组最后一个元素也就是当前LIS的下标。  对每个元素进行如下判断:

若nums[i]>b[end],则更新LIS,否则二分搜索b数组比nums[i]元素大的最小位置idx,此时b[idx]>nums[i]>b[idx-1] 更新idx位置,因为此时同样长度的子串,包含nums[i]的要比包含b[idx]要小。  时间复杂度O(nlogn)。

算法

1、

[java] view
plain copy

 





public int lengthOfLIS(int[] nums) {  

    if (nums.length == 0)  

        return 0;  

    int c[] = new int[nums.length];// c[i]表示从0~i 以nums[i]结尾的最长增长子串的长度  

    c[0] = 1;  

    int maxLength = 1;  

  

    for (int i = 1; i < nums.length; i++) {  

        int tmp = 1;  

        for (int j = 0; j < i; j++) {  

            if (nums[i] > nums[j]) {  

                tmp = Math.max(c[j] + 1, tmp);  

            }  

        }  

        c[i] = tmp;  

        maxLength = Math.max(maxLength, c[i]);  

    }  

  

    return maxLength;  

}  

2、

[java] view
plain copy

 





public int lengthOfLIS(int[] nums) {  

    if (nums.length == 0)  

        return 0;  

  

    int b[] = new int[nums.length + 1];// 长度为i的子串 最后一个数最小值  

    int end = 1;  

    b[end] = nums[0];  

  

    for (int i = 1; i < nums.length; i++) {  

        if (nums[i] > b[end]) {// 比最长子串最后元素还大,则更新最长子串长度  

            end++;  

            b[end] = nums[i];  

        } else {// 否则更新b数组  

            int idx = binarySearch(b, nums[i], end);  

            b[idx] = nums[i];  

        }  

    }  

    return end;  

}  

  

/** 

 * 二分查找大于t的最小值,并返回其位置 

 */  

public int binarySearch(int[] b, int target, int end) {  

    int low = 1, high = end;  

    while (low <= high) {  

        int mid = (low + high) / 2;  

        if (target > b[mid])  

            low = mid + 1;  

        else  

            high = mid - 1;  

    }  

    return low;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: