300.最长递增子序列
文章链接:代码随想录 (programmercarl.com)
思路:依旧是遵循动规五步曲
(1)确定dp数组含义
dp[i]表示从0到 i (包括 i )区间内的最长递增子序列的长度
(2)确定递推公式
dp[i]从区间[0,j]找寻到最长递增子序列的长度,其中j应当小于i
为了使得dp[i]在区间[0,j]中搜索时持续更新dp[i],且只有nums[i] > nums[j]时,长度+1
因此,dp[i] = Math.max(dp[i],dp[j] + 1);
(3)初始化
默认dp数组所有值为1,因为最短长度至少为1
(4)遍历顺序从前往后
(5)举例推导检验
Java代码:(思路如上)
class Solution {
public int lengthOfLIS(int[] nums) {
//先判断特殊情况
if(nums.length == 0 || nums == null){
return 0;
}
if(nums.length == 1){
return 1;
}
int len = nums.length;
int[] dp = new int[len];
//初始化
Arrays.fill(dp,1);
//存储最终结果
int res = 0;
for(int i = 1; i < len;i++){
for(int j = 0; j < i;j++){
if(nums[i] > nums[j]){
dp[i] = Math.max(dp[i],dp[j] + 1);
}
}
if(dp[i] > res) res = dp[i];
}
return res;
}
}
674. 最长连续递增序列
文章链接:代码随想录 (programmercarl.com)
思路:与300题不同的点在于,此题要求是连续的,因此只需要比较前后两个元素的值,无需像300一样从[0,j]依次比较,依旧遵循动规五步曲
(1)确定dp数组含义
dp[i] 表示在区间 [0,i] 中最长连续递增序列的长度为 dp[i]
(2)确定递推公式
与300题不同,此时dp[i]应当与 i 前一个 j 相比,如果nums[i] > nums[j],才可以相加
因此,if(nums[i] > nums[j]) dp[i] = Math.max(dp[i],dp[j] + 1);
(3)初始化
最短长度至少为1
(4)遍历顺序从前向后
(5)举例推导验证
Java代码:(思路如上)
class Solution {
public int findLengthOfLCIS(int[] nums) {
//先判断特殊情况
if(nums.length == 0 || nums == null){
return 0;
}
if(nums.length == 1){
return 1;
}
int len = nums.length;
//确定dp数组
int[] dp = new int[len];
//初始化
Arrays.fill(dp,1);
//使用一个res用来实时存储最后的值
int res = 0;
//确定递推公式以及遍历顺序
for(int i = 1; i < len;i++){
for(int j = i - 1; j < i;j++){
if(nums[i] > nums[j]){
//dp[i]在max里是为了一直更新dp[i]的值
dp[i] = Math.max(dp[i],dp[j] + 1);
}
}
if(dp[i] > res) res = dp[i];
}
return res;
}
}
718. 最长重复子数组
文章链接:代码随想录 (programmercarl.com)
思路:无思路
看完文章后的反思:
(1)确定dp数组的含义
dp[i][j] 表示在A数组的区间[0, i - 1] 上以 i - 1 下标结尾 和 B数组的区间 [0, j - 1] 上以 j - 1 下标结尾时 A和B最长重复子数组的长度为dp[i][j]
(2)确定递推公式
当 A[i - 1] == B[j - 1] 时,dp[i][j] = dp[i - 1][j - 1] + 1
(3)初始化
均初始化为0
(4)遍历顺序
外层A,内层B 或者 外层B,内层A 都可以,从前向后遍历
(5)举例推导验证
实现代码遇到的问题:
(1)定义dp数组长度自己写的是nums1.length与nums2.length,运行错误,改成如下就可以运行了
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
Java代码:(思路如上)
class Solution {
public int findLength(int[] nums1, int[] nums2) {
//先判断特殊情况
if(nums1.length == 0 || nums2.length == 0){
return 0;
}
int len1 = nums1.length;
int len2 = nums2.length;
//确定dp数组
int[][] dp = new int[len1 + 1][len2 + 1];
//初始化,数组默认均为0
//使用res来更新最终结果
int res = 0;
//确定递推公式以及遍历顺序
for(int i = 1; i < len1 + 1;i++){
for(int j = 1; j < len2 + 1;j++){
if(nums1[i - 1] == nums2[j - 1]){
dp[i][j] = dp[i - 1][j - 1] + 1;
res = Math.max(res,dp[i][j]);
}
}
}
return res;
}
}