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?
最长递增子序列是一道经典的题目。
在例子中,总共有8个数。为了计算在index = 7 的时候,最长的递增序列,我们先考虑index < 7的时候的递增子序列的情况。
我们开一个数组cache,cache[ i ] 存储 下标为 i 的时候,能达到的最大递增序列。
假设我们已经知道index <= i 的时候的最大递增序列,cache[ 0 ] ... cache[ 1 ] ... cache[ i ] 。
那么 i + 1的时候的最大递增序列是多少少?nums[ index ] < nums [ i + 1], 这意味着 nums [ i + 1]可以加到 nums [ index ] 的递增序列中去。
我们找到所有这样的index, 取max ( cache[ index ] ) 就是当前的能达到的最大的递增序列了。
对于[10, 9, 2, 5, 3, 7, 101, 18]
i = 0, 值为10,cache[ 0 ] = 1
i = 1, 值为9,不能跟1组合,cache[ 1 ] = 1
i = 2,值为2, cache[ 2 ] = 1
i = 3, 值为5, 5 > 2, 能和2组合,cache[ 3 ] = 1 + cache[ 2 ] = 2
i = 4,值为3,3 > 2,能和2组合, cache[ 4 ] = 1 + cache[ 2 ] = 2
i = 5, 值为7, 7 > 2, 7 > 5, 7 > 3, cache[ 5 ] = 1 + max ( cache[ 2 ] , cache[ 3 ] , cache[ 4 ] ) = 3
i = 6, 值为101, 101大于前面所有的,cache [ 5 ] = 1 + max (cache[ 0 ] ,... ,cache[ 5 ] ) = 4
i = 7, 值为18, 18大于除了101的, cache [ 7 ] = 1 + max( cache[ 0 ] , ... , cache [ 5 ] ) = 4
最后,cache数组中的最大值为递增序列最大长度。
时间复杂度O ( n ^ 2 )
空间复杂度 O ( n )
运行时间:
代码:
public class LongestIncreasingSubsequence {
public int lengthOfLIS(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[] cache = new int[nums.length];
cache[0] = 1;
int maxLen = 1;
for (int i = 1; i < nums.length; i++) {
int curNum = 1;
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
curNum = Math.max(curNum, cache[j] + 1);
}
}
cache[i] = curNum;
maxLen = Math.max(maxLen, curNum);
}
return maxLen;
}
}