问题描述
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(n2)解法:
定义数组dp[i]表示前i个数的最长递增序列的长度,则状态转移矩阵:
dp[i]=max(dp[j])+1,(j
public int lengthOfLIS(int[] nums) {
if(nums==null)
return 0;
int n=nums.length;
if(n==0)
return 0;
int[]dp=new int[n];
dp[0]=1;
int ans=1;
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[j]&&dp[i]<dp[j])
dp[i]=dp[j];
}
dp[i]++;
if(ans<dp[i])
ans=dp[i];
}
return ans;
}
O(nlogn)解法:二分查找
维护一个递增的序列,对其进行二分查找当前元素nums[i],覆盖原有元素或者在末尾添加。
代码:
public int lengthOfLIS(int[] nums) {
if(nums==null)
return 0;
int n=nums.length;
if(n==0)
return 0;
int[]dp=new int[n];
dp[0]=nums[0];
int len=1;
for(int i=1;i<n;i++){
int low=0,high=len-1;
while(low<=high){
int mid=low+(high-low)/2;
if(nums[i]<=dp[mid])
high=mid-1;
else
low=mid+1;
}
if(low>=len)
dp[len++]=nums[i];
else
dp[low]=nums[i];
}
return len;
}