题目描述
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目分析—动态规划(o(n^2))
1、用数组dp[i]表示以nums[i]结尾的最长上升子序列的长度
2、计算dp[i]的时候需要遍历dp[0]到dp[i-1]
3、选出其中dp[i]最大的如dp[j]并且还要满足nums[i]>nums[j]
4、dp[i]=dp[j]+1
5、否则,dp[i]=1;
通过代码
class Solution {
public int lengthOfLIS(int[] nums) {
if (nums.length==0) return 0;
int[] dp = new int[nums.length];
int res=1;
dp[0]=1;
for(int i=1;i<dp.length;i++){
int flag=0;
for(int j=i-1;j>=0;j--){
if (nums[i]>nums[j]){
flag=Math.max(dp[j],flag);
}
}
dp[i]=flag+1;
res=Math.max(res,dp[i]);
}
return res;
}
}
动态规划+二分查找(o(nlogn))
通过代码
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
int[] flag=new int[len];
int res=0;
for(int i=0;i<len;i++){
//最重要的是更新flag数组
int x=0,y=res;
while(x<y){
int mid=(x+y)/2;
if (flag[mid]<nums[i]) x=mid+1;
else y=mid;
}
flag[x]=nums[i];
if (res==y) res++;
}
return res;
}
}