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
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:
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.Follow up: Could you solve it using only O(s2.length)
additional memory space?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to checking if one string is an interleaving of two other strings is like trying every single way to merge those two strings together. We explore every possible combination of characters from each of the two strings to see if any of them match the third string.
Here's how the algorithm would work step-by-step:
def is_interleave_brute_force(first_string, second_string, combined_string):
def solve(first_string_index, second_string_index, current_string):
# If we've used all characters from both strings
if first_string_index == len(first_string) and second_string_index == len(second_string):
return current_string == combined_string
# Try taking a character from the first string
if first_string_index < len(first_string):
if solve(first_string_index + 1, second_string_index, current_string + first_string[first_string_index]):
return True
# Try taking a character from the second string
if second_string_index < len(second_string):
if solve(first_string_index, second_string_index + 1, current_string + second_string[second_string_index]):
return True
return False
# Start the recursive process
return solve(0, 0, "")
We need to figure out if a third string can be formed by mixing the characters from two other strings. The trick is to see if we can build the third string piece by piece, choosing characters from the first or second string, without getting stuck or making any impossible choices.
Here's how the algorithm would work step-by-step:
def is_interleave(first_string, second_string, third_string):
first_string_length = len(first_string)
second_string_length = len(second_string)
third_string_length = len(third_string)
if first_string_length + second_string_length != third_string_length:
return False
# dp[i][j] is True if third_string[0...i+j-1] is formed by
# interleaving first_string[0...i-1] and second_string[0...j-1]
dp_table = [[False] * (second_string_length + 1) for _ in range(first_string_length + 1)]
# Base case: Empty strings interleave to form an empty string
dp_table[0][0] = True
# Fill the DP table in bottom-up manner
for i in range(first_string_length + 1):
for j in range(second_string_length + 1):
if i > 0:
# Check if current char of first_string matches and previous state is True
if first_string[i - 1] == third_string[i + j - 1] and dp_table[i - 1][j]:
dp_table[i][j] = True
if j > 0:
# Check if current char of second_string matches and previous state is True
if second_string[j - 1] == third_string[i + j - 1] and dp_table[i][j - 1]:
dp_table[i][j] = True
# If the last cell is True, then the strings are interleaved
return dp_table[first_string_length][second_string_length]
Case | How to Handle |
---|---|
One or both input strings are null or empty. | Return true only if the third string is also null or empty, or handle appropriately based on the problem's requirements if only some are null or empty. |
The length of the third string does not equal the sum of the lengths of the first two strings. | Return false immediately as no interleaving is possible. |
Very long input strings (close to memory limits) leading to potential stack overflow with recursive solutions or memory issues with DP solutions. | Implement a dynamic programming solution with memoization or tabulation using bottom-up approach for avoiding stack overflow and optimize memory usage. |
Strings s1 and s2 are identical and combine to form s3 | The solution should correctly identify this as an interleaving without incorrectly using same characters from s1 or s2 twice. |
s3 contains characters not present in s1 or s2 | Return false since s3 cannot be formed by interleaving s1 and s2. |
One of the input strings is significantly longer than the other (e.g., |s1| >> |s2|). | Ensure that the algorithm does not have worst-case performance depending heavily on the length of the longer string. |
When s1 and s2 are very similar to s3, but a character is out of order. | The solution should return false, as only exact interleaving is permitted. |
The first character of s1 and s2 are the same, but only one creates a viable path | Backtracking with memoization should correctly check both paths when first characters match and choose the correct one. |