[LeetCode] 97. Interleaving String 交织相错的字符串
Given s1, s2, s3, 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