给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums.length==0) return 0;
int[]dp = new int[nums.length+1];
Arrays.fill(dp,1);
int res=1;
for(int i=1;i<nums.length;++i) {
for(int j=0;j<i;++j) {
if(nums[i]>nums[j]){
dp[i] = Integer.max(dp[i],dp[j]+1);
}
}
res = Integer.max(res,dp[i]);
}
return res;
}
}
还有一种方法,就是 遇到大的 +1 ,遇到小的,去前面的队伍里找到一个位置,把这个小的替换掉
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums.length<=1) return nums.length;
int[]dp = new int[nums.length+1];
// Arrays.fill(dp,1);
int p = 0;
dp[0] = nums[0];
for(int i=1;i<nums.length;++i) {
if(nums[i]>dp[p]) {
dp[++p] = nums[i];
}else{
int l=0,r = p;
while(l<r) {
int mid = (l+r)>>1;
if(dp[mid]<nums[i]) {
l = mid+1;
}else{
r = mid;
}
}
dp[l] = nums[i];
}
}
return p+1;
}
}
考虑一个简单的贪心,如果我们要使上升子序列尽可能的长,则我们需要让序列上升得尽可能慢,因此我们希望每次在上升子序列最后加上的那个数尽可能的小。