Description
Given strings s1, s2, and s3, find whether s3 is formed by an interleaving of s1 and s2.
An interleaving of two strings s and t is a configuration where they are divided into non-empty substrings such that:
s = s1 + s2 + … + sn
t = t1 + t2 + … + tm
|n - m| <= 1
The interleaving is s1 + t1 + s2 + t2 + s3 + t3 + … or t1 + s1 + t2 + s2 + t3 + s3 + …
Note: a + b is the concatenation of strings a and b.
Examples
Example 1:
Input: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”
Output: true
Example 2:
Input: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbbaccc”
Output: false
Example 3:
Input: s1 = “”, s2 = “”, s3 = “”
Output: true
Constraints:
0 <= s1.length, s2.length <= 100
0 <= s3.length <= 200
s1, s2, and s3 consist of lowercase English letters.
Follow up: Could you solve it using only O(s2.length) additional memory space? (I cant)
思路
-
最原始的思路就是递归了呀,设定一下终止条件(顺便剪下枝),然后一个一个char比较就可以了,但很明显,这个方法会导致TLE(代码附上了,不死心还是submit了一下)
-
正常做法应该就是dp了,这次用的是二维的dp,最开始想了很久,虽然把表格弄出来了,但是更新规则还是不清楚,去看了lc的solution,发现忘记了重要的一条:
- 如果 s1.substring(0, i) 和 s2.substring(0, j) 能构成 s3.substring(0, k),那么 k = i + j - 1
- 写成上面的形式是多么显而易见的事情啊,有了这个前提之后就可以构建2D表格了
-
以s1 = ddda, s2 = da, s3 = ddadda为例
初始dp表格如下
- | 0 | d | d | d | a |
---|---|---|---|---|---|
0 | |||||
d | |||||
a |
更新dp第0行和第0列
- | 0 | d | d | d | a |
---|---|---|---|---|---|
0 | T | dp[0][0]=T && s1[0]=s3[0+1-1] (T) | dp[0][1]=T && s1[1]=s3[0+2-1] (T) | dp[0][2]=T && s1[2]!=s3[0+3-1] (F) | dp[0][3]=F (F) |
d | dp[0][0]=T & s2[0]=s3[1+0-1] (T) | ||||
a | dp[1][0]=T & s2[1]!=s3[2+0-1] (F) |
根据更新公式:
d
p
[
i
]
[
j
]
=
(
d
p
[
i
−
1
]
[
j
]
&
&
s
1
[
i
−
1
]
=
=
s
3
[
i
+
j
−
1
]
)
∣
∣
(
d
p
[
i
]
[
j
−
1
]
&
&
s
2
[
j
−
1
]
=
=
s
3
[
i
+
j
−
1
]
)
dp[i][j] = (dp[i - 1][j] ~~\&\&~~ s1[i - 1] == s3[i + j - 1])~~ ||~~ (dp[i][j - 1] ~~\&\&~~ s2[j - 1] == s3[i + j - 1])
dp[i][j]=(dp[i−1][j] && s1[i−1]==s3[i+j−1]) ∣∣ (dp[i][j−1] && s2[j−1]==s3[i+j−1])
更新
- | 0 | d | d | d | a |
---|---|---|---|---|---|
0 | T | T | T | F | F |
d | T | 左边的T&上面的d和s3作比较(T) | 左边的T&上边的d和s3作比较d!=a / 上边的T&左边的d和s3作比较d!=a(F) | 左边和上面都是F(F) | 左边和上边都是F(F) |
a | F | 上边的T和左边的a作比较(T) | 左边的T&上边的d和s3作比较(T) | 左边的T&上边的d和s3作比较(T) | 左边的T&上边的a和s3作比较(T) |
代码
递归
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.equals("") && s2.equals("") && s3.equals(""))
return true;
if (s1.length() + s2.length() != s3.length())
return false;
if (s1.equals(""))
return s3.equals(s2);
if (s2.equals(""))
return s3.equals(s1);
if (s1.charAt(0) != s3.charAt(0) && s2.charAt(0) != s3.charAt(0))
return false;
if (s1.charAt(0) != s3.charAt(0))
return isInterleave(s1, s2.substring(1), s3.substring(1));
if (s2.charAt(0) != s3.charAt(0))
return isInterleave(s1.substring(1), s2, s3.substring(1));
return isInterleave(s1, s2.substring(1), s3.substring(1)) || isInterleave(s1.substring(1), s2, s3.substring(1));
}
}
DP
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length())
return false;
boolean dp[][] = new boolean[s1.length() + 1][s2.length() + 1];
dp[0][0] = true;
for (int i = 1; i < s1.length() + 1; i++)
dp[i][0] = dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1);
for (int i = 1; i < s2.length() + 1; i++)
dp[0][i] = dp[0][i - 1] && s2.charAt(i - 1) == s3.charAt(i - 1);
for (int i = 1; i < s1.length() + 1; i++){
for (int j = 1; j < s2.length() + 1; 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[s1.length()][s2.length()];
}
}