Problem 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 s and t are divided into n and m substrings respectively, such that:
s = s1 + s2 + ... + snt = t1 + t2 + ... + tm|n - m| <= 1- The interleaving is
s1 + t1 + s2 + t2 + s3 + t3 + ...ort1 + 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 Explanation: One way to obtain s3 is: Split s1 into s1 = "aa" + "bc" + "c" Split s2 into s2 = "dbbc" + "a" Interleaving the two splits: "aa" + "dbbc" + "bc" + "a" + "c" = "aadbbcbcac" 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
Python Solution
def isInterleave(s1: str, s2: str, s3: str) -> bool:
if len(s1) + len(s2) != len(s3):
return False
# dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
dp = [[False] * (len(s2) + 1) for _ in range(len(s1) + 1)]
dp[0][0] = True
# Initialize first row
for j in range(1, len(s2) + 1):
dp[0][j] = dp[0][j-1] and s2[j-1] == s3[j-1]
# Initialize first column
for i in range(1, len(s1) + 1):
dp[i][0] = dp[i-1][0] and s1[i-1] == s3[i-1]
# Fill the dp table
for i in range(1, len(s1) + 1):
for j in range(1, len(s2) + 1):
dp[i][j] = (dp[i-1][j] and s1[i-1] == s3[i+j-1]) or \
(dp[i][j-1] and s2[j-1] == s3[i+j-1])
return dp[len(s1)][len(s2)]
Java Solution
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length()) {
return false;
}
// dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
dp[0][0] = true;
// Initialize first row
for (int j = 1; j <= s2.length(); j++) {
dp[0][j] = dp[0][j-1] && s2.charAt(j-1) == s3.charAt(j-1);
}
// Initialize first column
for (int i = 1; i <= s1.length(); i++) {
dp[i][0] = dp[i-1][0] && s1.charAt(i-1) == s3.charAt(i-1);
}
// Fill the dp table
for (int i = 1; i <= s1.length(); i++) {
for (int j = 1; j <= s2.length(); 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()];
}
}
C++ Solution
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
if (s1.length() + s2.length() != s3.length()) {
return false;
}
// dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
vector> dp(s1.length() + 1, vector(s2.length() + 1, false));
dp[0][0] = true;
// Initialize first row
for (int j = 1; j <= s2.length(); j++) {
dp[0][j] = dp[0][j-1] && s2[j-1] == s3[j-1];
}
// Initialize first column
for (int i = 1; i <= s1.length(); i++) {
dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1];
}
// Fill the dp table
for (int i = 1; i <= s1.length(); i++) {
for (int j = 1; j <= s2.length(); j++) {
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]);
}
}
return dp[s1.length()][s2.length()];
}
};
JavaScript Solution
/**
* @param {string} s1
* @param {string} s2
* @param {string} s3
* @return {boolean}
*/
var isInterleave = function(s1, s2, s3) {
if (s1.length + s2.length !== s3.length) {
return false;
}
// dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
const dp = Array(s1.length + 1).fill().map(() => Array(s2.length + 1).fill(false));
dp[0][0] = true;
// Initialize first row
for (let j = 1; j <= s2.length; j++) {
dp[0][j] = dp[0][j-1] && s2[j-1] === s3[j-1];
}
// Initialize first column
for (let i = 1; i <= s1.length; i++) {
dp[i][0] = dp[i-1][0] && s1[i-1] === s3[i-1];
}
// Fill the dp table
for (let i = 1; i <= s1.length; i++) {
for (let j = 1; j <= s2.length; j++) {
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]);
}
}
return dp[s1.length][s2.length];
};
C# Solution
public class Solution {
public bool IsInterleave(string s1, string s2, string s3) {
if (s1.Length + s2.Length != s3.Length) {
return false;
}
// dp[i][j] represents if s3[0:i+j] is formed by interleaving s1[0:i] and s2[0:j]
bool[,] dp = new bool[s1.Length + 1, s2.Length + 1];
dp[0,0] = true;
// Initialize first row
for (int j = 1; j <= s2.Length; j++) {
dp[0,j] = dp[0,j-1] && s2[j-1] == s3[j-1];
}
// Initialize first column
for (int i = 1; i <= s1.Length; i++) {
dp[i,0] = dp[i-1,0] && s1[i-1] == s3[i-1];
}
// Fill the dp table
for (int i = 1; i <= s1.Length; i++) {
for (int j = 1; j <= s2.Length; j++) {
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]);
}
}
return dp[s1.Length, s2.Length];
}
}
Complexity Analysis
- Time Complexity: O(m × n) where m and n are the lengths of s1 and s2
- Space Complexity: O(m × n) for the dp table
Solution Explanation
This solution uses dynamic programming:
- Key concept:
- Use 2D DP table
- Track valid interleavings
- Build solution bottom-up
- Algorithm steps:
- Initialize base cases
- Fill first row and column
- Build dp table
- Check final state
Key points:
- Handle empty strings
- Check length condition
- Efficient DP solution
- Clear state transitions