[LeetCode] 97. 交错字符串

题目链接 : https://leetcode-cn.com/problems/interleaving-string/

题目描述:

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

示例:

示例 1:

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

示例 2:

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

思路:

思路一:动态规划

  • 自底向上

    动态方程:

    dp[i][j]表示s1的前i元素和s2j元素是否交错组成s3i+j元素

    所以有动态方程:

    dp[i][j] = (dp[i-1][j] && s3[i+j-1] == s1[i-1]) || (dp[i][j-1] && s2[j-1] == s3[i+j-1])

    注意:针对第一行,第一列要单独考虑

  • 自顶向下

思路二: BFS

代码:

class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        n1 = len(s1)
        n2 = len(s2)
        n3 = len(s3)
        if n1 + n2 != n3: return False

        dp = [[False] * (n2 + 1) for _ in range(n1 + 1)]

        dp[0][0] = True
        # 第一行
        for j in range(1, n2 + 1):
            dp[0][j] = (dp[0][j - 1] and s2[j - 1] == s3[j - 1])

        # 第一列
        for i in range(1, n1 + 1):
            dp[i][0] = (dp[i - 1][0] and s1[i - 1] == s3[i - 1])
        # print(dp)

        for i in range(1, n1 + 1):
            for j in range(1, n2 + 1):
                dp[i][j] = (dp[i - 1][j] and s1[i - 1] == s3[i + j - 1]) or (
                        dp[i][j - 1] and s2[j - 1] == s3[i + j - 1])
        # print(dp)
        return dp[-1][-1]

java

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n1 = s1.length();
        int n2 = s2.length();
        int n3 = s3.length();
        if (n1 + n2 != n3) return false;
        boolean[][] dp = new boolean[n1 + 1][n2 + 1];
        dp[0][0] = true;
        // 第一行
        for (int j = 1; j <= n2; j++) dp[0][j] = (dp[0][j - 1] && s2.charAt(j - 1) == s3.charAt(j - 1));
        // 第一列
        for (int i = 1; i <= n1; i++) dp[i][0] = (dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1));
        for (int i = 1; i <= n1; i++) {
            for (int j = 1; j <= n2; j++) {
                dp[i][j] = (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1));
            }
        }
        return dp[n1][n2]; 
    }
}

自顶向下

class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        import functools
        n1 = len(s1)
        n2 = len(s2)
        n3 = len(s3)
        @functools.lru_cache(None)
        def helper(i, j, k):
            if i == n1 and j == n2 and k == n3:
                return True
            if k < n3:
                if i < n1 and s1[i] == s3[k] and helper(i+1, j, k+1):
                    return True
                if j < n2 and s2[j] == s3[k] and helper(i, j+1, k+1):
                    return True
            return False
        return helper(0,0,0)

思路二:

class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        from collections import deque
        n1 = len(s1)
        n2 = len(s2)
        n3 = len(s3)
        if n1 + n2 != n3: return False

        queue = deque()
        queue.appendleft((0, 0))
        visited = set()
        while queue:
            i, j = queue.pop()
            if i == n1 and j == n2:
                return True
            if i < n1 and s1[i] == s3[i + j] and (i + 1, j) not in visited:
                visited.add((i + 1, j))
                queue.appendleft((i + 1, j))
            if j < n2 and s2[j] == s3[i + j] and (i, j + 1) not in visited:
                visited.add((i, j + 1))
                queue.appendleft((i, j + 1))
        return False

java

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n1 = s1.length();
        int n2 = s2.length();
        int n3 = s3.length();
        if (n1 + n2 != n3) return false;
        boolean[][] visited = new boolean[n1 + 1][n2 + 1];
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0, 0});
        while (!queue.isEmpty()) {
            int[] tmp = queue.poll();
            if (tmp[0] == n1 && tmp[1] == n2) return true;
            if (tmp[0] < n1 && s1.charAt(tmp[0]) == s3.charAt(tmp[0] + tmp[1]) && !visited[tmp[0] + 1][tmp[1]]) {
                visited[tmp[0] + 1][tmp[1]] = true;
                queue.offer(new int[]{tmp[0] + 1, tmp[1]});
            }
            if (tmp[1] < n2 && s2.charAt(tmp[1]) == s3.charAt(tmp[0] + tmp[1]) && !visited[tmp[0]][tmp[1] + 1]) {
                visited[tmp[0]][tmp[1] + 1] = true;
                queue.offer(new int[]{tmp[0], tmp[1] + 1});
            }

        }
        return false;
    }
}
原文地址:https://www.cnblogs.com/powercai/p/11066230.html