1143.最长公共子序列
题目链接/文章讲解:代码随想录
视频讲解:动态规划子序列问题经典题目 | LeetCode:1143.最长公共子序列_哔哩哔哩_bilibili
class Solution {public int longestCommonSubsequence(String text1, String text2) {// 将输入字符串转换为字符数组char[] nums1 = text1.toCharArray();char[] nums2 = text2.toCharArray();// 创建一个二维数组 dp,用于存储子问题的解// dp[i][j] 表示 text1 的前 i 个字符与 text2 的前 j 个字符的最长公共子序列长度int[][] dp = new int[nums1.length + 1][nums2.length + 1];// 遍历字符数组,用 i 和 j 作为索引for (int i = 1; i <= nums1.length; i++) {for (int j = 1; j <= nums2.length; j++) {// 如果当前字符相等,则最长公共子序列长度加1if (nums1[i - 1] == nums2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {// 如果不相等,取之前的最大值dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);}}}// 返回最长公共子序列的长度return dp[nums1.length][nums2.length];}
}
1035.不相交的线
题目链接/文章讲解:代码随想录
视频讲解:动态规划之子序列问题,换汤不换药 | LeetCode:1035.不相交的线_哔哩哔哩_bilibili
class Solution {// 方法:计算两个数组中未交叉的最大连线数public int maxUncrossedLines(int[] nums1, int[] nums2) {// 创建一个二维数组 dp,用于存储子问题的解// dp[i][j] 表示 nums1 的前 i 个元素和 nums2 的前 j 个元素的最大未交叉线数int[][] dp = new int[nums1.length + 1][nums2.length + 1];// 遍历 nums1 和 nums2 的每一个元素for (int i = 1; i <= nums1.length; i++) {for (int j = 1; j <= nums2.length; j++) {// 如果 nums1 的当前元素与 nums2 的当前元素相等if (nums1[i - 1] == nums2[j - 1]) {// 则可以在当前元素之间画一条线,增加一条连线dp[i][j] = dp[i - 1][j - 1] + 1;} else {// 如果不相等,则取前一个状态的最大值// dp[i][j] = max(dp[i-1][j], dp[i][j-1])dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);}}}// 返回 dp 数组中最后一个元素,代表 nums1 和 nums2 的最大未交叉线数return dp[nums1.length][nums2.length];}
}
53. 最大子序和
题目链接/文章讲解:代码随想录
视频讲解:看起来复杂,其实是简单动态规划 | LeetCode:53.最大子序和_哔哩哔哩_bilibili
class Solution {public int maxSubArray(int[] nums) {// 初始化dp数组和maxSum变量int[] dp = new int[nums.length];dp[0] = nums[0];int maxSum = dp[0]; // 初始最大值为第一个元素for (int i = 1; i < nums.length; i++) {// 计算以 nums[i] 结尾的最大子数组和dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);// 更新最大子数组和maxSum = Math.max(maxSum, dp[i]);}return maxSum;}
}
392.判断子序列
题目链接/文章讲解:代码随想录
视频讲解:动态规划,用相似思路解决复杂问题 | LeetCode:392.判断子序列_哔哩哔哩_bilibili
class Solution {// 定义一个方法,检查字符串 s 是否为字符串 t 的子序列public boolean isSubsequence(String s, String t) {// 将字符串 s 和 t 转换为字符数组char[] nums1 = s.toCharArray();char[] nums2 = t.toCharArray();// 创建一个二维数组 dp,用于动态规划,行数为 nums1.length + 1,列数为 nums2.length + 1// dp[i][j] 表示 nums1 的前 i 个字符与 nums2 的前 j 个字符的最长公共子序列的长度int[][] dp = new int[nums1.length + 1][nums2.length + 1];// 遍历 nums1 和 nums2 的每个字符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][j - 1], dp[i - 1][j]);}}}// 如果 dp[nums1.length][nums2.length] 等于 nums1.length,说明 s 是 t 的子序列if (dp[nums1.length][nums2.length] == nums1.length) {return true; // 是子序列} else {return false; // 不是子序列}}
}