LeetCode300.最长递增子序列
题目链接:300.最长递增子序列
思路
-
第一步,确定dp数组以及其下标的含义:
dp[i]
表示i
之前且包含以nums[i]
结尾的最长递增子序列的长度。 -
第二步,确定递推公式:
-
求从
0
到i- 1
各个位置的最长递增子序列的长度 + 1,前提条件是nums[i] > nums[j]
,其中 j 是从 0 到 i - 1 的遍历。 -
所以,递推公式为
d p [ i ] = M a t h . m a x ( d p [ i ] , d p [ j ] + 1 ) dp[i] = Math.max(dp[i], dp[j] + 1) dp[i]=Math.max(dp[i],dp[j]+1)
-
-
第三步,初始化:从递推公式可以得,每个最长子序列得长度至少为 1。所以,对整个
dp
数组进行初始化为 1。 -
第四步,遍历:
- 首先从 0 到 i - 1进行遍历整个
nums
数组。 - 其次在第二层循环中,从 0 遍历到
i - 1
得出以nums[i]
结尾的最长递增子序列的长度。
- 首先从 0 到 i - 1进行遍历整个
代码
class Solution {
public int lengthOfLIS(int[] nums) {
if (nums.length <= 1){
return nums.length;
}
int[] dp = new int[nums.length];
for (int i = 0; i < nums.length; i++){
dp[i] = 1;
}
int result = 0;
for (int i = 1; i < nums.length; i++){
for (int j = 0; j < i; j++){
if (nums[i] > nums[j]){
dp[i] = Math.max(dp[j] + 1, dp[i]);
}
}
result = Math.max(dp[i], result);
}
return result;
}
}
LeetCode 674. 最长连续递增序列
题目链接:674. 最长连续递增序列
思路
-
第一步,确定 dp 数组及其下标的含义:
dp[i]
表示i
之前且包含以nums[i]
结尾的连续递增子序列的长度。 -
第二步,确定递推公式:
-
由于是连续递增子序列,所以,本题仅需比较
nums[i]
和nums[i - 1]
之间的大小即可。 -
所以,递推公式为,当
nums[i] > nums[i - 1]
d p [ i ] = d p [ i − 1 ] + 1 dp[i] = dp[i - 1] + 1 dp[i]=dp[i−1]+1
-
-
第三步,初始化:每个连续递增的子序列的长度至少为 1。所以,对整个
dp
数组进行初始化为 1。 -
第四步,遍历顺序:从递推公式可以得出
dp[i]
的值需要dp[i - 1]
推出,所以,遍历顺序为从前往后遍历。
代码:
public int findLengthOfLCIS(int[] nums) {
if (nums.length == 0){
return 0;
}
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
int result = 1;
for (int i = 1; i < nums.length; i++){
if (nums[i] > nums[i - 1]){
dp[i] = dp[i - 1] + 1;
}
// System.out.println("****************");
// System.out.println(dp[i]);
if (dp[i] > result){
result = dp[i];
}
}
return result;
}
LeetCode718.最长重复子数组
题目连接:718.最长重复子数组
思路
-
第一步,首先确定dp数组以及下标的含义:采用二维数组,
dp[i][j]
表示以下标i- 1
的nums1
和以下标j - 1
的nums2
,最长重复子数组的长度。 -
第二步,确定递推公式:
- 通过对
dp
数组的分析可以得出,dp[i][j]
的状态由dp[i - 1][j - 1]
推出。所以递推公式为
d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + 1 dp[i][j] = dp[i - 1][j - 1] + 1 dp[i][j]=dp[i−1][j−1]+1
- 通过对
-
第三步,初始化:对于
dp[i][0]
和dp[0][j]
初始化为 0 。 -
第四步,确定遍历顺序:
- 对于外层循环,遍历数组
nums1
,内层遍历数组nums2
。(对于nums1
和nums2
谁是外层遍历,谁是内层遍历没有区别)
- 对于外层循环,遍历数组
代码
class Solution {
public int findLength(int[] nums1, int[] nums2) {
int result = 0;
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
for (int i = 1; i < nums1.length + 1; i++){
for (int j = 1; j < nums2.length + 1; j++){
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;
}
}