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?
Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.
思路:这道题我最开始以为和最大长方形那道题一样呢,用一个栈就能解决。结果试了一下,样例不通过。
看看O(N^2)的复杂度,果断动态规划。简单的动态规划不难,问题是O(NlogN)的那个真没想出来,挺巧妙的。
class Solution {
/**
* 普通的动态规划,对于每一个位置,计算到此为止位置的最大长度,每个dp中保存的是到每个位置为止的最大长度,复杂度N^2
*/
public int lengthOfLIS1(int[] nums) {
if(nums.length == 0) return 0;
int[] dp = new int[nums.length];
for(int i = 0;i<nums.length ;i++){
dp[i] = 1;
for(int j = 0;j < i ; j++){
if(nums[i] > nums[j]){
dp[i] = Math.max(dp[i],dp[j] + 1) ;
}
}
}
int max = 0;
for(int i = 0; i<nums.length ; i++){
max = Math.max(max,dp[i]);
}
return max;
}
/**
*改进的动态规划,整个dp数组中保存的是最大长度的子序列(len表示其长度),而且是高度最矮的那条子序列(因为在0到len范围二分搜索时,如果新插入的值比原值 *小,则将原值替换掉了),并且因为最大值始终插入到dp数组末尾,所以dp数组可以使用二分搜索
*/
public int lengthOfLIS(int[] nums) {
if(nums.length == 0) return 0;
int[] dp = new int[nums.length];
int len = 0;
for(int num :nums){
int i = Arrays.binarySearch(dp,0,len,num);
if(i<0) i = - (i + 1);//这个和自动实现的二分搜索算法返回值有关,求出的是应该插入的位置(当前数组位置插)
dp[i] = num;
if(i == len ){
len++;
}
}
return len;
}
}