LeetCode - 97 Interleaving String

LeetCode - 97 Interleaving String

LAVI

Medium

97. Interleaving String

題目

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 s and t are divided into n and m substrings respectively, 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.

Example 1

Example

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true
Explanation: One way to obtain s3 is:
Split s1 into s1 = "aa" + "bc" + "c", and s2 into s2 = "dbbc" + "a".
Interleaving the two splits, we get "aa" + "dbbc" + "bc" + "a" + "c" = "aadbbcbcac".
Since s3 can be obtained by interleaving s1 and s2, we return true.

Example 2

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
Output: false
Explanation: Notice how it is impossible to interleave s2 with any other string to obtain s3.

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.

解題思路

經典字串 DP 題
判斷 s3 能不能由 s1s2 交錯組成

  • 先檢查長度:

    • 如果 s1.size() + s2.size() != s3.size()
    • 代表不可能組成,直接回傳 false
  • DP 定義:

    • dp[i][j]:代表 s1 的前 i 個字和 s2 的前 j 個字,能不能組成 s3 的前 i + j 個字
  • 初始化:

    • dp[0][0] = true
    • 代表兩個空字串可以組成空字串
  • 狀態轉移:

    • 如果目前要接的是 s1[i-1]

      • i > 0s1[i-1] == s3[i+j-1]
      • 代表可以從 dp[i-1][j] 轉移過來
        dp[i][j] = dp[i][j] || dp[i-1][j]
    • 如果目前要接的是 s2[j-1]

      • j > 0s2[j-1] == s3[i+j-1]
      • 代表可以從 dp[i][j-1] 轉移過來
        dp[i][j] = dp[i][j] || dp[i][j-1]
  • 這裡用 || 是因為:

    • 只要 dp[i-1][j]dp[i][j-1] 其中一個可以成立
    • dp[i][j] 就可以成立
  • 最後答案:

    • dp[n][m]

Solution Code

Time Complexity
O(n × m)

Space Complexity
O(n × m)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int n = s1.size(), m = s2.size();
if(n + m != s3.size()) return false;

vector<vector<bool>> dp(n+1, vector<bool>(m+1, false)); // dp[i][j] 代表 s1 的 i 個和 s2 的 j 個

dp[0][0] = true;

for(int i = 0; i <= n; ++i){
for(int j = 0; j <= m; ++j){
if(i > 0 && s1[i-1] == s3[i+j-1]){
dp[i][j] = dp[i][j] || dp[i-1][j]; // || 因為是 true or false 只要 dp[i-1][j] 和 dp[i][j-1] 有人是 true 就好
}
if(j > 0 && s2[j-1] == s3[i+j-1]){
dp[i][j] = dp[i][j] || dp[i][j-1]; // || 因為是 true or false 只要 dp[i-1][j] 和 dp[i][j-1] 有人是 true 就好
}
}
}
return dp[n][m];
}
};
On this page
LeetCode - 97 Interleaving String