题目:
分析:最长上升子序列的组合可能有很多,但只要求出长度即可,比较容易想到动归规划的做法,当前位置的最大上升子序列长度取决于子问题的最优解(之前的最大上升子序列长度),注意是当前位置的最大上升子序列长度,不是到目前位置的最大长度,可以用一个数组来记录结果
注意: 整个问题的最优解不是数组的最后一个值,因为最优解不一定出现在最后
代码:
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums == null || nums.length == 0){
return 0;
}
//整个问题的最优解,一开始至少有一个
int maxLen = 1;
int[] dp = new int[nums.length];
dp[0] = 1;
for(int i = 1; i < nums.length; i++){
//记录当前位置i之前的最大上升子序列长度
int currentMax = 0;
for(int j = 0; j < i; j++){
//只有比之前位置的元素大才进行currentMax 的更新
if(nums[i] > nums[j]){
currentMax = Math.max(currentMax, dp[j]);
}
}
//因为currentMax 记录当前位置i之前的最大上升子序列长度,所以+1,加的i这个
dp[i] = currentMax+1;
//更新整个问题的最优解,直接可以输出返回
maxLen = Math.max(maxLen, dp[i]);
}
return maxLen;
}
}
用动态规划做的时间复杂度是n^2, 有另一种思路:用贪心+二分的时间复杂度是nlogn