📝 Problem Details
- Title:
97. Interleaving String
- Link: https://leetcode.com/problems/interleaving-string/
- Difficulty: Medium
- Tags/Categories: Dynamic-Programming
input strings
s1
s2
s3
find whethers3
is formed by an interleaving ofs1 and s2
What is an interleaving string?
- A string
s3
is an interleaving ofs1
ands2
if it maintains the relative order of characters from boths1
ands2
, but they can be interleaved together. - It does not mean the characters are shuffled randomly.
- Example:
s1 = "abc"
s2 = "def"
s3 = "adbcef" ✅ (valid interleaving)
s3 = "abdecf" ❌ (invalid, order changed)
💡 Explanation of Solution
Intuitive Subproblem:
- We need to check if `s3` can be formed by **interleaving** `s1` and `s2`.
- Interleaving means characters from `s1` and `s2` appear in the **same relative order**, but they can be interspersed.
- Example:
s1 = "abc", s2 = "def"
s3 = "adbcef" ✅ (valid interleaving)
s3 = "abdecf" ❌ (invalid because order changed)
- At every step, we either:
1. Take the next character from `s1`.
2. Take the next character from `s2`.
Top-Down or Bottom Up?:
- **Bottom-Up Approach is Preferred** because:
- It avoids deep recursion (stack overflow risk in large inputs).
- We can efficiently fill a DP table iteratively.
- It allows **space optimization** to `O(m)`, reducing memory usage.
- **Top-Down Approach (Recursion + Memoization) is also possible**, but has higher overhead due to recursion.
DP State:
- use a 2d dp table where dp[i][j] is:
- i represents how many characters we have taken from s1
- j represents how many characters we have taken from s2
- dp[i][j] is true if the first i+j characters of s3 can be formed by interleaving the first i characters of s1 and first j characters of s2
State Transition:
- If `dp[i-1][j]` is `true` and `s1[i-1] == s3[i+j-1]`, then `dp[i][j] = true`.
- If `dp[i][j-1]` is `true` and `s2[j-1] == s3[i+j-1]`, then `dp[i][j] = true`.
- the answer should be at dp[s1.size()][s2.size()]
⌛ Complexity Analysis
Time Complexity: O(n * m)
Space Complexity: O(n * m)
💻 Implementation of Solution
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
int n = s1.size(), m = s2.size(), l = s3.size();
// If the total length of s1 and s2 doesn't match s3, it's impossible to interleave them
if (n + m != l) return false;
// Create a 2D DP table, initialized to false
// dp[i][j] = true means the first i characters of s1 and the first j characters of s2
// can successfully interleave to form the first i + j characters of s3.
vector<vector<bool>> dp(n + 1, vector<bool>(m + 1, false));
// Base Case: If all strings are empty, they trivially interleave
dp[0][0] = true;
// Fill the DP table
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
// Check if we can take a character from s1
if (i > 0 && s1[i - 1] == s3[i + j - 1]) {
// If we were previously able to interleave up to dp[i-1][j], then we can extend it
dp[i][j] = dp[i][j] || dp[i - 1][j];
}
// Check if we can take a character from s2
if (j > 0 && s2[j - 1] == s3[i + j - 1]) {
// If we were previously able to interleave up to dp[i][j-1], then we can extend it
dp[i][j] = dp[i][j] || dp[i][j - 1];
}
}
}
// Our answer is in the bottom-right corner of the table
// If dp[n][m] is true, s3 is a valid interleaving of s1 and s2
return dp[n][m];
}
};