码迷,mamicode.com
首页 > 其他好文 > 详细

Longest Increasing Subsequence

时间:2019-12-21 22:42:03      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:markdown   lin   长度   The   sort   ref   ++   put   default   

Description

Given a sequence of integers, find the longest increasing subsequence (LIS).

You code should return the length of the LIS.

 

Clarification

What‘s the definition of longest increasing subsequence?

  • The longest increasing subsequence problem is to find a subsequence of a given sequence in which the subsequence‘s elements are in sorted order, lowest to highest, and in which the subsequence is as long as possible. This subsequence is not necessarily contiguous, or unique.

  • https://en.wikipedia.org/wiki/Longest_increasing_subsequence

Example

Example 1:
	Input:  [5,4,1,2,3]
	Output:  3
	
	Explanation:
	LIS is [1,2,3]


Example 2:
	Input: [4,2,4,5,3,7]
	Output:  4
	
	Explanation: 
	LIS is [2,4,5,7]

Challenge

Time complexity O(n^2) or O(nlogn)

 

思路:

O(n2) 解法:

Dp[i] 表示以第i个数字为结尾的最长上升子序列的长度。
对于每个数字,枚举前面所有小于自己的数字 j,Dp[i] = max{Dp[j]} + 1. 如果没有比自己小的,Dp[i] = 1;

O(nlogn)解法:

使用一个辅助空间B数组。
B[i]存储Dp值为i的最小的数字。(有多个位置,以这些位置为结尾的LIS长度都为i, 则这些数字中最小的一个存在B[i]中)
则B数组严格递增。且下标表示LIS长度,也是严格递增,可以在B数组中进行二分查找。

对于每个位置i,我们要找,所有小于A[i], 且Dp值最大的那个。这个操作在B数组中二分查找。

public class Solution {
    /**
     * @param nums: An integer array
     * @return: The length of LIS (longest increasing subsequence)
     */
    public int longestIncreasingSubsequence(int[] nums) {
        int []f = new int[nums.length];
        int max = 0;
        for (int i = 0; i < nums.length; i++) {
            f[i] = 1;
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    f[i] = f[i] > f[j] + 1 ? f[i] : f[j] + 1;
                }
            }
            if (f[i] > max) {
                max = f[i];
            }
        }
        return max;
    }
}

O(nlogn)解法:

public class Solution {
    /**
     * @param nums: An integer array
     * @return: The length of LIS (longest increasing subsequence)
     */
    public int longestIncreasingSubsequence(int[] nums) {
        int[] minLast = new int[nums.length + 1];
        minLast[0] = Integer.MIN_VALUE;
        for (int i = 1; i <= nums.length; i++) {
            minLast[i] = Integer.MAX_VALUE;
        }
        
        for (int i = 0; i < nums.length; i++) {
            // find the first number in minLast >= nums[i]
            int index = binarySearch(minLast, nums[i]);
            minLast[index] = nums[i];
        }
        
        for (int i = nums.length; i >= 1; i--) {
            if (minLast[i] != Integer.MAX_VALUE) {
                return i;
            }
        }
        
        return 0;
    }
    
    // find the first number > num
    private int binarySearch(int[] minLast, int num) {
        int start = 0, end = minLast.length - 1;
        while (start + 1 < end) {
            int mid = (end - start) / 2 + start;
            if (minLast[mid] < num) {
                start = mid;
            } else {
                end = mid;
            }
        }
        
        return end;
    }
}

  

  

Longest Increasing Subsequence

标签:markdown   lin   长度   The   sort   ref   ++   put   default   

原文地址:https://www.cnblogs.com/FLAGyuri/p/12078260.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!