Longest Increasing Subsequence
Posted ShinningWu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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?
解答:这道题利用了bianrysearch和dynamic programming方法。新建一个数组存储递增数列,遍历原数组,对每个元素都在递增数组中使用Arrays的binarySearch方法寻找该元素。
感觉这题的重点是对binarySearch方法使用的融会贯通。从下面的javadoc可以看到:
1)找到key元素,返回key元素下标;
2)没找到key元素,返回(-(insertion point) - 1).其中insertion point为第一个比key元素大的元素的index,如果都比key小,则为toIndex。
public static int binarySearch(int[] a, int fromIndex, int toIndex, int key) Searches a range of the specified array of ints for the specified value using the binary search algorithm. The range must be sorted (as by the sort(int[], int, int) method) prior to making this call. If it is not sorted, the results are undefined. If the range contains multiple elements with the specified value, there is no guarantee which one will be found. Parameters: a - the array to be searched fromIndex - the index of the first element (inclusive) to be searched toIndex - the index of the last element (exclusive) to be searched key - the value to be searched for Returns: index of the search key, if it is contained in the array within the specified range; otherwise, (-(insertion point) - 1). The insertion point is defined as the point at which the key would be inserted into the array: the index of the first element in the range greater than the key, or toIndex if all elements in the range are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found. Throws: IllegalArgumentException - if fromIndex > toIndex ArrayIndexOutOfBoundsException - if fromIndex < 0 or toIndex > a.length Since: 1.6
利用这两点,当该数组元素没找到key元素时,将insertion point处的元素替换为key元素,且如果key元素是在末尾新加时,将结果加1.
代码如下:
public class Solution { public int lengthOfLIS(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int[] dp = new int[nums.length]; int len = 0; for (int i = 0; i < nums.length; i++) { int index = Arrays.binarySearch(dp, 0, len, nums[i]); if (index < 0) { index = - (index + 1); } dp[index] = nums[i]; if (index == len) { len++; } } return len; } }
值得注意的是,这个保存递增数列的数组最终存的长度为len的递增数列不一定就是实际的结果序列,虽然其长度与结果序列相同。
比如nums为[2,3,4,1],最后len为3,dp中的数列为[1,3,4]。
这个题目的解法确实很巧妙,有一些小细节值得仔细思考。
以上是关于Longest Increasing Subsequence的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Longest Increasing Subsequence
Longest Increasing Subsequence
674. Longest Continuous Increasing Subsequence