刷题找工作!!!
题目链接
自己的思路
dp[i]表示在第n个数字上,现在的最长递增子序列。
如果num[i]大于nums[i],长度再加1,否则继承前面dp[i-1]的最大长度。
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
if(len == 1)
return 1;
int[] dp = new int[len + 1];
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= len ; i++){
if(nums[i - 1] > nums[i-2]){
dp[i] = dp[i-1] + 1;
}else{
dp[i] = dp[i-1];
}
System.out.println(dp[i]);
}
return dp[len];
}
}
但想一想,我这样的思路是有问题的,并没有确保整个数列是递增的,只是计算了相邻两个数之间是递增的对数。
看来不能小瞧动态规划题。
正确答案
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
if(len == 1)
return 1;
int[] dp = new int[len];
//转变思路,dp[n]一定是满足n这个数存在的
dp[0] = 1;
int ans = 1;
for(int i = 1; i < len;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);
}
}
ans = Math.max(dp[i], ans);
}
//最后不是直接输出dp[len - 1]
//而是遍历所有输出最大值
return ans;
}
}
已经理解了,这样看这道题不难,注意3个点
- dp[i]表示当i算进去子序列时最大的长度
- 输出最大值而不是dp[len - 1]
- 不要害怕时间复杂度,O(n^2)也是有可能的