跳到主要内容

Interleaving String

描述

Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.

For example, Given: s1 = "aabcc", s2 = "dbbca",

When s3 = "aadbbcbcac", return true.

When s3 = "aadbbbaccc", return false.

分析

设状态f[i][j],表示s1[0,i]s2[0,j],匹配s3[0, i+j]。如果 s1 的最后一个字符等于 s3 的最后一个字符,则f[i][j]=f[i-1][j];如果 s2 的最后一个字符等于 s3 的最后一个字符,则f[i][j]=f[i][j-1]。因此状态转移方程如下:

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

递归

# Interleaving String
# 递归,会超时,仅用来帮助理解
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
if len(s3) != len(s1) + len(s2):
return False
if not s1 or not s2:
return True

return self.is_interleave_helper(s1, 0, len(s1),
s2, 0, len(s2),
s3, 0, len(s3))

def is_interleave_helper(self, s1: str, begin1: int, end1: int,
s2: str, begin2: int, end2: int,
s3: str, begin3: int, end3: int) -> bool:
if begin3 == end3:
return begin1 == end1 and begin2 == end2

return (begin1 < end1 and s1[begin1] == s3[begin3] and
self.is_interleave_helper(s1, begin1 + 1, end1,
s2, begin2, end2,
s3, begin3 + 1, end3)) or \
(begin2 < end2 and s2[begin2] == s3[begin3] and
self.is_interleave_helper(s1, begin1, end1,
s2, begin2 + 1, end2,
s3, begin3 + 1, end3))

动规

// Interleaving String
// 二维动规,时间复杂度O(n^2),空间复杂度O(n^2)
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if (s3.length() != s1.length() + s2.length())
return false;

boolean[][] f = new boolean[s1.length() + 1][s2.length() + 1];
for (int i = 0; i < s1.length() + 1; ++i)
Arrays.fill(f[i], true);

for (int i = 1; i <= s1.length(); ++i)
f[i][0] = f[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1);

for (int i = 1; i <= s2.length(); ++i)
f[0][i] = f[0][i - 1] && s2.charAt(i - 1) == s3.charAt(i - 1);

for (int i = 1; i <= s1.length(); ++i)
for (int j = 1; j <= s2.length(); ++j)
f[i][j] = (s1.charAt(i - 1) == s3.charAt(i + j - 1) && f[i - 1][j])
|| (s2.charAt(j - 1) == s3.charAt(i + j - 1) && f[i][j - 1]);

return f[s1.length()][s2.length()];
}
}

动规+滚动数组

// Interleaving String
// 二维动规+滚动数组,时间复杂度O(n^2),空间复杂度O(n)
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length())
return false;

if (s1.length() < s2.length())
return isInterleave(s2, s1, s3);

boolean[] f = new boolean[s2.length() + 1];
Arrays.fill(f, true);

for (int i = 1; i <= s2.length(); ++i)
f[i] = s2.charAt(i - 1) == s3.charAt(i - 1) && f[i - 1];

for (int i = 1; i <= s1.length(); ++i) {
f[0] = s1.charAt(i - 1) == s3.charAt(i - 1) && f[0];

for (int j = 1; j <= s2.length(); ++j)
f[j] = (s1.charAt(i - 1) == s3.charAt(i + j - 1) && f[j])
|| (s2.charAt(j - 1) == s3.charAt(i + j - 1) && f[j - 1]);
}

return f[s2.length()];
}
}