Interleaving String
MEDIUMDescription
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.
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", 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 <= 1000 <= s3.length <= 200s1,s2, ands3consist of lowercase English letters.
Follow up: Could you solve it using only O(s2.length) additional memory space?
Approaches
Checkout 4 different approaches to solve Interleaving String. Click on different approaches to view the approach and algorithm in detail.
Brute-Force Recursion
This approach uses a simple recursive function to explore all possible ways of forming s3 by picking characters from s1 and s2. It directly models the decision process: at each character of s3, we decide whether to match it with the current character of s1 or s2. If a character in s3 matches both, we explore both possibilities recursively.
Algorithm
- The core idea is to use a recursive function, say
check(i, j), which determines if the rest ofs3(from indexi+j) can be formed by the rest ofs1(from indexi) and the rest ofs2(from indexj). - First, perform a preliminary check: if
s1.length() + s2.length() != s3.length(), it's impossible to forms3, so returnfalse. - Base Case: If we have successfully traversed all of
s1ands2(i.e.,i == s1.length()andj == s2.length()), it means we have successfully formeds3. Returntrue. - Recursive Step: At the current state
(i, j), we are trying to matchs3.charAt(i+j).- If
s1.charAt(i)matchess3.charAt(i+j), we make a recursive callcheck(i + 1, j). If this call returnstrue, we have found a valid interleaving. - If
s2.charAt(j)matchess3.charAt(i+j), we make a recursive callcheck(i, j + 1). If this call returnstrue, we have also found a valid interleaving. - The result for
check(i, j)istrueif either of the possible recursive calls returnstrue. - If neither character matches or if the subsequent recursive calls return
false, this path is invalid.
- If
The method involves a helper function that takes two pointers, i for s1 and j for s2, indicating the number of characters already used from each string. The current character to be matched in s3 is at index k = i + j.
If the current character of s3 matches the character at s1[i], we recursively call the function with i+1. If it matches s2[j], we recursively call with j+1. If it matches both, we try both paths and return true if either path leads to a solution. The recursion stops when we have successfully used all characters from both s1 and s2.
public class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if (s1.length() + s2.length() != s3.length()) {
return false;
}
return check(s1, s2, s3, 0, 0);
}
private boolean check(String s1, String s2, String s3, int i, int j) {
// Base case: if we have reached the end of all strings
if (i == s1.length() && j == s2.length()) {
return true;
}
boolean match1 = false;
if (i < s1.length() && s1.charAt(i) == s3.charAt(i + j)) {
match1 = check(s1, s2, s3, i + 1, j);
}
// If the first path was successful, no need to check the second
if (match1) {
return true;
}
boolean match2 = false;
if (j < s2.length() && s2.charAt(j) == s3.charAt(i + j)) {
match2 = check(s1, s2, s3, i, j + 1);
}
return match2;
}
}
Complexity Analysis
Pros and Cons
- Simple to understand and implement.
- Directly translates the problem definition into code.
- Extremely inefficient due to a large number of redundant computations for the same subproblems (i.e., the same
iandjvalues are computed multiple times through different recursive paths). - Will likely result in a 'Time Limit Exceeded' error on most online judges for non-trivial inputs.
Code Solutions
Checking out 4 solutions in different languages for Interleaving String. Click on different languages to view the code.
public class Solution {
public bool IsInterleave(string s1, string s2, string s3) {
int m = s1.Length, n = s2.Length;
if (m + n != s3.Length) {
return false;
}
bool[] f = new bool[n + 1];
f[0] = true;
for (int i = 0; i <= m; ++i) {
for (int j = 0; j <= n; ++j) {
int k = i + j - 1;
if (i > 0) {
f[j] &= s1[i - 1] == s3[k];
}
if (j > 0) {
f[j] |= (f[j - 1] & s2[j - 1] == s3[k]);
}
}
}
return f[n];
}
}Video Solution
Watch the video walkthrough for Interleaving String
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.