给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums==null||nums.length==0)
return 0;
int m=nums.length;
int [] dp=new int [m];
int max=1;//最小的就是每一个数字长度为1
for(int i=0;i<m;i++){//以i结尾的最大子序列长度
dp[i]=1;
for(int j=0;j<i;j++)
{
if(nums[j]<nums[i]){
dp[i]=Math.max(dp[i],dp[j]+1);//原来dp[i]是1,如果前面有子序列结尾的前一个值比他小,就把dp[j]+1,然后取两者较大的,其实就可以拿三个数来慢慢分析
max=Math.max(dp[i],max);//这步很常规
}
}
}
return max;
}
}
class Solution {
public int lengthOfLIS(int[] nums) {
/**
dp[i]: 所有长度为i+1的递增子序列中, 最小的那个序列尾数.
由定义知dp数组必然是一个递增数组, 可以用 maxL 来表示最长递增子序列的长度.
对数组进行迭代, 依次判断每个数num将其插入dp数组相应的位置:
1. num > dp[maxL], 表示num比所有已知递增序列的尾数都大, 将num添加入dp
数组尾部, 并将最长递增序列长度maxL加1
2. dp[i-1] < num <= dp[i], 只更新相应的dp[i]
**/
int maxL = 0;
int[] dp = new int[nums.length];
for(int num : nums) {
// 二分法查找, 也可以调用库函数如binary_search
int lo = 0, hi = maxL;
while(lo < hi) {
int mid = lo+(hi-lo)/2;
if(dp[mid] < num)
lo = mid+1;
else
hi = mid;
}
dp[lo] = num;
if(lo == maxL)
maxL++;
}
return maxL;
}
}