LeetCode 97. 交错字符串

目录结构

1.题目

2.题解

2.1动态规划

2.2动态规划+空间优化


1.题目

给定三个字符串 s1s2s3, 验证 s3 是否是由 s1 和 s2 交错组成的。

示例:

输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true


输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/interleaving-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2.题解

2.1动态规划

dp[i][j]表示s1的前i个字符和s2的前j个字符能否交替组成s3的前i+j个字符:

  • 若s1[i-1] == s3[i+j-1](即s1的第i个字符和s3的第i+j个字符相等),且dp[i-1][j] == true(即s1的前i-1个字符和s2的前j个字符能交替组成s3的前i+j-1个字符),则dp[i][j] = true;
  • 否则,若s2[j-1] == s3[i+j-1](即s2的第j个字符和s3的第i+j个字符相等),且dp[i][j-1] == true(即s1的前i个字符和s2的前j-1个字符能交替组成s3的前i+j-1个字符),则dp[i][j] = true;
  • 否则,dp[i][j] = false。
public class Solution97 {

    @Test
    public void test97() {
        String s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac";
        System.out.println(isInterleave(s1, s2, s3));
    }

    public boolean isInterleave(String s1, String s2, String s3) {
        int len1 = s1.length(), len2 = s2.length(), len3 = s3.length();
        if (len1 + len2 != len3) {
            return false;
        }
        boolean[][] dp = new boolean[len1 + 1][len2 + 1];
        dp[0][0] = true;
        for (int i = 0; i <= len1; i++) {
            for (int j = 0; j <= len2; j++) {
                int p = i + j - 1;
                if (i > 0) {
                    dp[i][j] = dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(p);
                }
                if (j > 0) {
                    dp[i][j] = dp[i][j] || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(p));
                }
            }
        }
        return dp[len1][len2];
    }
}
  • 时间复杂度:O(mn)
  • 空间复杂度:O(mn)

2.2动态规划+空间优化

从2.1的状态转移方程可知,dp计算时只和相邻两行数据有关,故只需存储最近一行。

public class Solution97 {

    @Test
    public void test97() {
        String s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac";
        System.out.println(isInterleave(s1, s2, s3));
    }

    public boolean isInterleave(String s1, String s2, String s3) {
        int len1 = s1.length(), len2 = s2.length(), len3 = s3.length();
        if (len1 + len2 != len3) {
            return false;
        }
        boolean[] dp = new boolean[len2 + 1];
        dp[0] = true;
        for (int i = 0; i <= len1; i++) {
            for (int j = 0; j <= len2; j++) {
                int p = i + j - 1;
                if (i > 0) {
                    dp[j] = dp[j] && s1.charAt(i - 1) == s3.charAt(p);
                }
                if (j > 0) {
                    dp[j] = dp[j] || (dp[j - 1] && s2.charAt(j - 1) == s3.charAt(p));
                }
            }
        }
        return dp[len2];
    }
}
  • 时间复杂度:O(mn)
  • 空间复杂度:O(n)

你可能感兴趣的:(LeetCode,leetcode)