1143.最长公共子序列
思路:动态规划五步曲:
- dp[i][j] 表示text1的0 - i-1和text2的0 - j-1的公共子序列长度
- 递推公式:
主要是两种情况:text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同,直接看代码
if (arr1[i - 1] == arr2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
- 初始化第一行和第一列为0
- 遍历顺序为从前到后,从上往下遍历
- 举例说明
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
// dp[i][j] 表示text1的0 - i-1和text2的0 - j-1的公共子序列长度
char[] arr1 = text1.toCharArray();
char[] arr2 = text2.toCharArray();
int[][] dp = new int[arr1.length + 1][arr2.length + 1];
for (int i = 1; i <= arr1.length; i++) {
for (int j = 1; j <= arr2.length; j++) {
if (arr1[i - 1] == arr2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
//System.out.print(dp[i][j]);
}
}
return dp[arr1.length][arr2.length];
}
}
1035.不相交的线
思路:可以分析一下,本题说是求最大的连线个数,其实本质上就是求两个数列最长公共子序列长度。
动态规划分析过程与上一题完全相同。
class Solution {
public int maxUncrossedLines(int[] nums1, int[] nums2) { // 其实是求最长公共子序列
// dp[i][j] 表示nums1从0到i,nums2从0到j,可以绘制的最大连线数
int[][] dp = new int[nums1.length + 1][nums2.length + 1];
// 递推公式:
for (int i = 1; i <= nums1.length; i++) {
for (int j = 1; j <= nums2.length; j++) {
if (nums1[i - 1] == nums2[j - 1]) dp[i][j] = dp[i -1][j - 1] + 1;
else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
return dp[nums1.length][nums2.length];
}
}
53. 最大子序和
思路:动态规划五步曲:
- dp[i]:包括下标i之前的最大连续子序列和为dp[i]
- 递推公式,dp[i] = max(dp[i - 1] + nums[i], nums[i]);
- 初始化dp[0] = nums[0]
- 遍历顺序为从前到后遍历
- 举例说明
class Solution {
public int maxSubArray(int[] nums) {
// dp[i] 表示从0到i nums的最大子序列和
int[] dp = new int[nums.length];
dp[0] = nums[0];
int res = dp[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
if (dp[i] > res) res = dp[i];
}
return res;
}
}