最长递增子序列
子序列不一定连续,子串一定连续
dp
https://leetcode.cn/problems/longest-increasing-subsequence/
- 明确状态:即原问题和子问题中一直发生变化的量,此处就是递增子序列的长度呗
- 明确选择:dp[i]可以选择的前面一部分就是dp[0…i-1]
- 明确base case:dp[i]显然至少为1,
- 明确dp函数/数组的含义:dp[i]表示以nums[i]做结尾的子序列的最大长度,那整个dp函数的结果不就是返回dp[]中的最大值吗
- 明确状态转移:数学归纳?比如dp[0…i-1]已经求出来了,怎么获得dp[i]?
class Solution {
public int lengthOfLIS(int[] nums) {
if(nums==null||nums.length==0) return 0;
int[] dp = new int[nums.length];
Arrays.fill(dp,1);
for(int i=0;i<nums.length;i++){
for(int j=0;j<i;j++){
//找可以做dp[i]前一部分的dp[j]
if(nums[i]>nums[j]){
dp[i]=Math.max(dp[i],dp[j]+1);
}
}
}
int res=dp[0];
for(int i=1;i<dp.length;i++){
if(dp[i]>res){
res=dp[i];
}
}
return res;
}
}
Conclusion
-
要区分子序列和子串的区别
-
dp难点是如何定义状态和如何转移,常借助数学归纳的思想(自底向上的),即利用前面的部分如何去推出后面的结果