300. 最长递增子序列
题目讲解:代码随想录
重点:
- 理解dp数组的含义,遍历顺序以及递推公式。
思路:
- dp数组的含义
// dp[i]表示以nums[i]结尾的最长递增子序列的长度 int[] dp = new int[nums.length];
- 递推公式
// 如果i之前的元素小于i, 那么用递推公式进行更新 if (nums[j] < nums[i]) { // 注意这里不是要dp[i]与dp[j]+1进行比较,而是我们要取dp[j]+1的最大值 dp[i] = Math.max(dp[i], dp[j] + 1); }
- dp数组的初始化
// 每个元素以自身为结尾长度肯定都是1 Arrays.fill(dp, 1);
- 遍历顺序
// 先用i来遍历元素当作结尾 for (int i = 1; i < nums.length; i++) // 再遍历i之前的元素 for (int j = 0; j < i; j++)
- 模拟dp数组
public int lengthOfLIS(int[] nums) {
if (nums.length == 1) return 1;
int result = 1;
// dp[i]表示以nums[i]结尾的最长递增子序列的长度
int[] dp = new int[nums.length];
// 每个元素以自身为结尾长度肯定都是1
Arrays.fill(dp, 1);
// 先用i来遍历元素当作结尾
for (int i = 1; i < nums.length; i++) {
// 再遍历i之前的元素
for (int j = 0; j < i; j++) {
// 如果之前的元素小于i, 那么用递推公式进行更新
if (nums[j] < nums[i]) {
// 注意这里不是要dp[i]与dp[j]+1进行比较,而是我们要取dp[j]+1的最大值
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
result = Math.max(result, dp[i]);
}
return result;
}
674. 最长连续递增序列
题目讲解:代码随想录
重点:
- 理解递推公式
思路:
- dp数组的含义
// 以nums[i]结尾的最长连续递增序列的长度 int[] dp = new int[nums.length];
- 递推公式
// 如果当前i比i-1大, 说明连续递增, 更新dp[i] if (nums[i - 1] < nums[i]) { dp[i] = dp[i - 1] + 1; }
- dp数组的初始化
// 每个以自己为结尾, 长度就是1 Arrays.fill(dp , 1);
- 遍历顺序
// 从前往后遍历, 一层遍历就可以, 因为要求连续 for (int i = 1; i < nums.length; i++)
- 模拟dp数组
public int findLengthOfLCIS(int[] nums) {
if (nums.length == 1) return 1;
int result = 1;
// 以nums[i]结尾的最长连续递增序列的长度
int[] dp = new int[nums.length];
// 每个以自己为结尾, 长度就是1
Arrays.fill(dp , 1);
// 从前往后遍历, 一层遍历就可以, 因为要求连续
for (int i = 1; i < nums.length; i++) {
// 如果当前i比i-1大, 说明连续递增, 更新dp[i]
if (nums[i - 1] < nums[i]) {
dp[i] = dp[i - 1] + 1;
}
result = Math.max(result, dp[i]);
}
return result;
}
718. 最长重复子数组
题目讲解:代码随想录
重点:
1.思路:
- dp数组的含义
// 以下标i-1为结尾的A, 和以下标j-1为结尾的B, 最长重复子数组长度为dp[i][j] int[][] dp = new int[nums1.length + 1][nums2.length + 1];
- 递推公式
// 当A[i-1]和B[j-1]相等时 if (nums1[i - 1] == nums2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; }
- dp数组的初始化
// 为了方便递归公式dp[i][j] = dp[i-1][j-1] + 1, 所以dp[i][0]和dp[0][j]初始化为0
- 遍历顺序
// 从前往后遍历A for (int i = 1; i < nums1.length + 1; i++) // 从前往后遍历B for (int j = 1; j < nums2.length + 1; j++)
- 模拟dp数组
public int findLength(int[] nums1, int[] nums2) {
int result = 0;
// 以下标i-1为结尾的A, 和以下标j-1为结尾的B, 最长重复子数组长度为dp[i][j]
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
// 从前往后遍历A
for (int i = 1; i < nums1.length + 1; i++) {
// 从前往后遍历B
for (int j = 1; j < nums2.length + 1; j++) {
// 当A[i-1]和B[j-1]相等时
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
result = Math.max(result, dp[i][j]);
}
}
}
return result;
}