1143. 最长公共子序列

Problem: 1143. 最长公共子序列

文章目录

  • 思路
  • 解题方法
  • 复杂度
  • Code

思路

这是一道经典的动态规划问题,我们需要找到两个字符串的最长公共子序列。我们可以使用一个二维数组dp,其中dp[i][j]表示字符串s1的前i个字符和字符串s2的前j个字符的最长公共子序列的长度。

解题方法

我们首先初始化一个(n+1) * (m+1)的二维数组dp,然后从左到右,从上到下遍历这个数组。对于每一个元素dp[i][j],我们比较s1的第i个字符和s2的第j个字符,如果它们相等,那么dp[i][j]就等于dp[i-1][j-1] + 1,否则dp[i][j]就等于max(dp[i-1][j], dp[i][j-1])。最后,dp[n][m]就是我们要找的答案。

复杂度

时间复杂度:

O ( n ∗ m ) O(n*m) O(nm),其中n和m分别是字符串s1和s2的长度。我们需要遍历整个dp数组来找到答案。

空间复杂度:

O ( n ∗ m ) O(n*m) O(nm),我们需要一个二维数组dp来存储所有的状态。

Code

class Solution {
    public int longestCommonSubsequence(String str1, String str2) {
        char[] s1 = str1.toCharArray();
        char[] s2 = str2.toCharArray();
        int n = s1.length;
        int m = s2.length;
        int[][] dp = new int[n + 1][m + 1];
        for (int len1 = 1; len1 <= n; len1++) {
            for (int len2 = 1; len2 <= m; len2++) {
                if (s1[len1 - 1] == s2[len2 - 1]) {
                    // ans = f3(s1, s2, len1 - 1, len2 - 1, dp) + 1;
                    dp[len1][len2] = dp[len1 - 1][len2 - 1] + 1;
                } else {
                    // ans = Math.max(f3(s1, s2, len1 - 1, len2, dp), f3(s1, s2, len1, len2 - 1, dp));
                    dp[len1][len2] = Math.max(dp[len1 - 1][len2], dp[len1][len2 - 1]);
                }
            }
        }
        return dp[n][m];
    }

}

你可能感兴趣的:(刷题,算法,leetcode,动态规划)