• [LeetCode] 97. Interleaving String 交织相错的字符串


    Given s1s2s3, find whether s3 is formed by the interleaving of s1and s2.

    Example 1:

    Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
    Output: true
    

    Example 2:

    Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
    Output: false

    给定字符串s1, s2, s3,求s3是否可以由s1和s2交错形成。

    解法:DP动态规划,

    递推公式为:

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

    其中dp[i][j] 表示的是 s2 的前 i 个字符和 s1 的前 j 个字符是否匹配 s3 的前 i+j 个字符

    Java:

    public boolean isInterleave(String s1, String s2, String s3) {
    
        if ((s1.length()+s2.length())!=s3.length()) return false;
    
        boolean[][] matrix = new boolean[s2.length()+1][s1.length()+1];
    
        matrix[0][0] = true;
    
        for (int i = 1; i < matrix[0].length; i++){
            matrix[0][i] = matrix[0][i-1]&&(s1.charAt(i-1)==s3.charAt(i-1));
        }
    
        for (int i = 1; i < matrix.length; i++){
            matrix[i][0] = matrix[i-1][0]&&(s2.charAt(i-1)==s3.charAt(i-1));
        }
    
        for (int i = 1; i < matrix.length; i++){
            for (int j = 1; j < matrix[0].length; j++){
                matrix[i][j] = (matrix[i-1][j]&&(s2.charAt(i-1)==s3.charAt(i+j-1)))
                        || (matrix[i][j-1]&&(s1.charAt(j-1)==s3.charAt(i+j-1)));
            }
        }
    
        return matrix[s2.length()][s1.length()];
    
    }
    

    Python:

    # O(m*n) space
    def isInterleave1(self, s1, s2, s3):
        r, c, l= len(s1), len(s2), len(s3)
        if r+c != l:
            return False
        dp = [[True for _ in xrange(c+1)] for _ in xrange(r+1)]
        for i in xrange(1, r+1):
            dp[i][0] = dp[i-1][0] and s1[i-1] == s3[i-1]
        for j in xrange(1, c+1):
            dp[0][j] = dp[0][j-1] and s2[j-1] == s3[j-1]
        for i in xrange(1, r+1):
            for j in xrange(1, c+1):
                dp[i][j] = (dp[i-1][j] and s1[i-1] == s3[i-1+j]) or 
                   (dp[i][j-1] and s2[j-1] == s3[i-1+j])
        return dp[-1][-1]
    

    Python:

    # O(2*n) space
    def isInterleave2(self, s1, s2, s3):
        l1, l2, l3 = len(s1)+1, len(s2)+1, len(s3)+1
        if l1+l2 != l3+1:
            return False
        pre = [True for _ in xrange(l2)]
        for j in xrange(1, l2):
            pre[j] = pre[j-1] and s2[j-1] == s3[j-1]
        for i in xrange(1, l1):
            cur = [pre[0] and s1[i-1] == s3[i-1]] * l2
            for j in xrange(1, l2):
                cur[j] = (cur[j-1] and s2[j-1] == s3[i+j-1]) or 
                         (pre[j] and s1[i-1] == s3[i+j-1])
            pre = cur[:]
        return pre[-1]
    

    Python:

    # O(n) space
    def isInterleave3(self, s1, s2, s3):
        r, c, l= len(s1), len(s2), len(s3)
        if r+c != l:
            return False
        dp = [True for _ in xrange(c+1)] 
        for j in xrange(1, c+1):
            dp[j] = dp[j-1] and s2[j-1] == s3[j-1]
        for i in xrange(1, r+1):
            dp[0] = (dp[0] and s1[i-1] == s3[i-1])
            for j in xrange(1, c+1):
                dp[j] = (dp[j] and s1[i-1] == s3[i-1+j]) or (dp[j-1] and s2[j-1] == s3[i-1+j])
        return dp[-1]
    

    Python:

    # DFS 
    def isInterleave4(self, s1, s2, s3):
        r, c, l= len(s1), len(s2), len(s3)
        if r+c != l:
            return False
        stack, visited = [(0, 0)], set((0, 0))
        while stack:
            x, y = stack.pop()
            if x+y == l:
                return True
            if x+1 <= r and s1[x] == s3[x+y] and (x+1, y) not in visited:
                stack.append((x+1, y)); visited.add((x+1, y))
            if y+1 <= c and s2[y] == s3[x+y] and (x, y+1) not in visited:
                stack.append((x, y+1)); visited.add((x, y+1))
        return False
    

    Python:  

    # BFS 
    def isInterleave(self, s1, s2, s3):
        r, c, l= len(s1), len(s2), len(s3)
        if r+c != l:
            return False
        queue, visited = [(0, 0)], set((0, 0))
        while queue:
            x, y = queue.pop(0)
            if x+y == l:
                return True
            if x+1 <= r and s1[x] == s3[x+y] and (x+1, y) not in visited:
                queue.append((x+1, y)); visited.add((x+1, y))
            if y+1 <= c and s2[y] == s3[x+y] and (x, y+1) not in visited:
                queue.append((x, y+1)); visited.add((x, y+1))
        return False
    

    Python:

    # Time:  O(m * n)
    # Space: O(m + n)
    class Solution(object):
        # @return a boolean
        def isInterleave(self, s1, s2, s3):
            if len(s1) + len(s2) != len(s3):
                return False
            if len(s1) > len(s2):
                return self.isInterleave(s2, s1, s3)
            match = [False for i in xrange(len(s1) + 1)]
            match[0] = True
            for i in xrange(1, len(s1) + 1):
                match[i] = match[i -1] and s1[i - 1] == s3[i - 1]
            for j in xrange(1, len(s2) + 1):
                match[0] = match[0] and s2[j - 1] == s3[j - 1]
                for i in xrange(1, len(s1) + 1):
                    match[i] = (match[i - 1] and s1[i - 1] == s3[i + j - 1]) 
                                           or (match[i] and s2[j - 1] == s3[i + j - 1])
            return match[-1]
    

    Python:

    # Time:  O(m * n)
    # Space: O(m * n)
    # Dynamic Programming
    class Solution2(object):
        # @return a boolean
        def isInterleave(self, s1, s2, s3):
            if len(s1) + len(s2) != len(s3):
                return False
            match = [[False for i in xrange(len(s2) + 1)] for j in xrange(len(s1) + 1)]
            match[0][0] = True
            for i in xrange(1, len(s1) + 1):
                match[i][0] = match[i - 1][0] and s1[i - 1] == s3[i - 1]
            for j in xrange(1, len(s2) + 1):
                match[0][j] = match[0][j - 1] and s2[j - 1] == s3[j - 1]
            for i in xrange(1, len(s1) + 1):
                for j in xrange(1, len(s2) + 1):
                    match[i][j] = (match[i - 1][j] and s1[i - 1] == s3[i + j - 1]) 
                                           or (match[i][j - 1] and s2[j - 1] == s3[i + j - 1])
            return match[-1][-1]
    

    Python:  

    # Time:  O(m * n)
    # Space: O(m * n)
    # Recursive + Hash
    class Solution3(object):
        # @return a boolean
        def isInterleave(self, s1, s2, s3):
            self.match = {}
            if len(s1) + len(s2) != len(s3):
                return False
            return self.isInterleaveRecu(s1, s2, s3, 0, 0, 0)
    
        def isInterleaveRecu(self, s1, s2, s3, a, b, c):
            if repr([a, b]) in self.match.keys():
                return self.match[repr([a, b])]
    
            if c == len(s3):
                return True
    
            result = False
            if a < len(s1) and s1[a] == s3[c]:
                result = result or self.isInterleaveRecu(s1, s2, s3, a + 1, b, c + 1)
            if b < len(s2) and s2[b] == s3[c]:
                result = result or self.isInterleaveRecu(s1, s2, s3, a, b + 1, c + 1)
    
            self.match[repr([a, b])] = result
    
            return result

    C++:

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

      

     

    类似题目:

    [LeetCode] 139. Word Break 单词拆分

    [LeetCode] 140. Word Break II 单词拆分II

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    1337:【例3-2】单词查找树
    1336:【例3-1】找树根和孩子
    1301:大盗阿福
    CSP-J/S 第一轮知识点选讲
    【转】C++STL各容器的操作及复杂度
    如何查看SUSE的版本信息
    野人和传教士过河问题的C语言源代码
    ubuntu如何安装软件
    Heavy Transportation POJ
    Heavy Transportation POJ
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9795773.html
Copyright © 2020-2023  润新知