|
| 1 | +--- |
| 2 | +id: Interleaving-Strings |
| 3 | +title: Interleaving Strings |
| 4 | +sidebar_label: Interleaving Strings |
| 5 | +tags: |
| 6 | + - Dynamic Programming |
| 7 | + - Strings |
| 8 | + - Interleaving String |
| 9 | +--- |
| 10 | + |
| 11 | +## Problem Description |
| 12 | + |
| 13 | +| Problem Statement | Solution Link | LeetCode Profile | |
| 14 | +| :------------------------------------------------------ | :------------------------------------------------------------------------- | :------------------------------------------------------ | |
| 15 | +| [Interleaving-Strings](https://leetcode.com/problems/Interleaving-Strings/description/) | [Interleaving-Strings Solution on LeetCode](https://leetcode.com/problems/Interleaving-Strings/solutions/) | [Nikita Saini](https://leetcode.com/u/Saini_Nikita/) | |
| 16 | + |
| 17 | +## Problem Description |
| 18 | + |
| 19 | +Given strings `s1`, `s2`, and `s3`, determine whether `s3` is formed by an interleaving of `s1` and `s2`. |
| 20 | + |
| 21 | +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: |
| 22 | + |
| 23 | +- `s = s1 + s2 + ... + sn` |
| 24 | +- `t = t1 + t2 + ... + tm` |
| 25 | +- `|n - m| <= 1` |
| 26 | + |
| 27 | +The interleaving is `s1 + t1 + s2 + t2 + s3 + t3 + ...` or `t1 + s1 + t2 + s2 + t3 + s3 + ...`. |
| 28 | + |
| 29 | +**Note:** `a + b` is the concatenation of strings `a` and `b`. |
| 30 | + |
| 31 | +### Examples |
| 32 | + |
| 33 | +#### Example 1: |
| 34 | + |
| 35 | +**Input:** `s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"` |
| 36 | +**Output:** `true` |
| 37 | +**Explanation:** |
| 38 | +One way to obtain `s3` is: |
| 39 | +Split `s1` into `s1 = "aa" + "bc" + "c"`, and `s2` into `s2 = "dbbc" + "a"`. |
| 40 | +Interleaving the two splits, we get `"aa" + "dbbc" + "bc" + "a" + "c" = "aadbbcbcac"`. |
| 41 | +Since `s3` can be obtained by interleaving `s1` and `s2`, we return `true`. |
| 42 | + |
| 43 | +#### Example 2: |
| 44 | + |
| 45 | +**Input:** `s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"` |
| 46 | +**Output:** `false` |
| 47 | +**Explanation:** |
| 48 | +Notice how it is impossible to interleave `s2` with any other string to obtain `s3`. |
| 49 | + |
| 50 | +#### Example 3: |
| 51 | + |
| 52 | +**Input:** `s1 = "", s2 = "", s3 = ""` |
| 53 | +**Output:** `true` |
| 54 | + |
| 55 | + |
| 56 | +### Constraints |
| 57 | +- $0 \leq \text{s1.length}, \text{s2.length} \leq 100$ |
| 58 | +- $0 \leq \text{s3.length} \leq 200$ |
| 59 | +- $\text{s1}$, $\text{s2}$, and $\text{s3}$ consist of lowercase English letters.$ |
| 60 | + |
| 61 | +## Approach |
| 62 | + |
| 63 | +To determine if `s3` is an interleaving of `s1` and `s2`, we can use dynamic programming. We define a 2D boolean DP array `dp` where `dp[i][j]` represents whether `s3[0:i+j]` can be formed by interleaving `s1[0:i]` and `s2[0:j]`. |
| 64 | + |
| 65 | +### Step-by-Step Algorithm |
| 66 | + |
| 67 | +1. Initialize a 2D DP array `dp` of size `(len(s1) + 1) x (len(s2) + 1)`. |
| 68 | +2. `dp[0][0]` is `True` because an empty `s3` can be formed by interleaving two empty strings. |
| 69 | +3. Fill the first row and column of `dp`: |
| 70 | + - `dp[i][0]` is `True` if `s1[:i]` matches `s3[:i]`. |
| 71 | + - `dp[0][j]` is `True` if `s2[:j]` matches `s3[:j]`. |
| 72 | +4. Fill the rest of the `dp` array: |
| 73 | + - `dp[i][j]` is `True` if either of the following is `True`: |
| 74 | + - `dp[i-1][j]` is `True` and `s1[i-1] == s3[i+j-1]` |
| 75 | + - `dp[i][j-1]` is `True` and `s2[j-1] == s3[i+j-1]` |
| 76 | +5. The result is `dp[len(s1)][len(s2)]`. |
| 77 | + |
| 78 | +## Solution in Python |
| 79 | + |
| 80 | +```python |
| 81 | +class Solution: |
| 82 | + def isInterleave(self, s1: str, s2: str, s3: str) -> bool: |
| 83 | + if len(s1) + len(s2) != len(s3): |
| 84 | + return False |
| 85 | + |
| 86 | + dp = [[False] * (len(s2) + 1) for _ in range(len(s1) + 1)] |
| 87 | + dp[0][0] = True |
| 88 | + |
| 89 | + for i in range(1, len(s1) + 1): |
| 90 | + dp[i][0] = dp[i-1][0] and s1[i-1] == s3[i-1] |
| 91 | + |
| 92 | + for j in range(1, len(s2) + 1): |
| 93 | + dp[0][j] = dp[0][j-1] and s2[j-1] == s3[j-1] |
| 94 | + |
| 95 | + for i in range(1, len(s1) + 1): |
| 96 | + for j in range(1, len(s2) + 1): |
| 97 | + 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]) |
| 98 | + |
| 99 | + return dp[len(s1)][len(s2)] |
| 100 | +``` |
| 101 | + |
| 102 | +## Solution in Java |
| 103 | +```java |
| 104 | +class Solution { |
| 105 | + public boolean isInterleave(String s1, String s2, String s3) { |
| 106 | + if (s1.length() + s2.length() != s3.length()) { |
| 107 | + return false; |
| 108 | + } |
| 109 | + |
| 110 | + boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1]; |
| 111 | + dp[0][0] = true; |
| 112 | + |
| 113 | + for (int i = 1; i <= s1.length(); i++) { |
| 114 | + dp[i][0] = dp[i-1][0] && s1.charAt(i-1) == s3.charAt(i-1); |
| 115 | + } |
| 116 | + |
| 117 | + for (int j = 1; j <= s2.length(); j++) { |
| 118 | + dp[0][j] = dp[0][j-1] && s2.charAt(j-1) == s3.charAt(j-1); |
| 119 | + } |
| 120 | + |
| 121 | + for (int i = 1; i <= s1.length(); i++) { |
| 122 | + for (int j = 1; j <= s2.length(); j++) { |
| 123 | + 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)); |
| 124 | + } |
| 125 | + } |
| 126 | + |
| 127 | + return dp[s1.length()][s2.length()]; |
| 128 | + } |
| 129 | +} |
| 130 | +``` |
| 131 | + |
| 132 | +## Solution in C++ |
| 133 | +```cpp |
| 134 | +class Solution { |
| 135 | +public: |
| 136 | + bool isInterleave(string s1, string s2, string s3) { |
| 137 | + if (s1.length() + s2.length() != s3.length()) { |
| 138 | + return false; |
| 139 | + } |
| 140 | + |
| 141 | + vector<vector<bool>> dp(s1.length() + 1, vector<bool>(s2.length() + 1, false)); |
| 142 | + dp[0][0] = true; |
| 143 | + |
| 144 | + for (int i = 1; i <= s1.length(); i++) { |
| 145 | + dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1]; |
| 146 | + } |
| 147 | + |
| 148 | + for (int j = 1; j <= s2.length(); j++) { |
| 149 | + dp[0][j] = dp[0][j-1] && s2[j-1] == s3[j-1]; |
| 150 | + } |
| 151 | + |
| 152 | + for (int i = 1; i <= s1.length(); i++) { |
| 153 | + for (int j = 1; j <= s2.length(); j++) { |
| 154 | + 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]); |
| 155 | + } |
| 156 | + } |
| 157 | + |
| 158 | + return dp[s1.length()][s2.length()]; |
| 159 | + } |
| 160 | +}; |
| 161 | +``` |
| 162 | +
|
| 163 | +## Solution in C |
| 164 | +```c |
| 165 | +#include <stdbool.h> |
| 166 | +#include <string.h> |
| 167 | +
|
| 168 | +bool isInterleave(char* s1, char* s2, char* s3) { |
| 169 | + int len1 = strlen(s1), len2 = strlen(s2), len3 = strlen(s3); |
| 170 | + if (len1 + len2 != len3) { |
| 171 | + return false; |
| 172 | + } |
| 173 | + |
| 174 | + bool dp[len1 + 1][len2 + 1]; |
| 175 | + memset(dp, false, sizeof(dp)); |
| 176 | + dp[0][0] = true; |
| 177 | + |
| 178 | + for (int i = 1; i <= len1; i++) { |
| 179 | + dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1]; |
| 180 | + } |
| 181 | + |
| 182 | + for (int j = 1; j <= len2; j++) { |
| 183 | + dp[0][j] = dp[0][j-1] && s2[j-1] == s3[j-1]; |
| 184 | + } |
| 185 | + |
| 186 | + for (int i = 1; i <= len1; i++) { |
| 187 | + for (int j = 1; j <= len2; j++) { |
| 188 | + 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]); |
| 189 | + } |
| 190 | + } |
| 191 | + |
| 192 | + return dp[len1][len2]; |
| 193 | +} |
| 194 | +``` |
| 195 | + |
| 196 | +## Solution in JavaScript |
| 197 | +```js |
| 198 | +var isInterleave = function(s1, s2, s3) { |
| 199 | + if (s1.length + s2.length !== s3.length) { |
| 200 | + return false; |
| 201 | + } |
| 202 | + |
| 203 | + const dp = Array(s1.length + 1).fill(false).map(() => Array(s2.length + 1).fill(false)); |
| 204 | + dp[0][0] = true; |
| 205 | + |
| 206 | + for (let i = 1; i <= s1.length; i++) { |
| 207 | + dp[i][0] = dp[i-1][0] && s1[i-1] === s3[i-1]; |
| 208 | + } |
| 209 | + |
| 210 | + for (let j = 1; j <= s2.length; j++) { |
| 211 | + dp[0][j] = dp[0][j-1] && s2[j-1] === s3[j-1]; |
| 212 | + } |
| 213 | + |
| 214 | + for (let i = 1; i <= s1.length; i++) { |
| 215 | + for (let j = 1; j <= s2.length; j++) { |
| 216 | + 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]); |
| 217 | + } |
| 218 | + } |
| 219 | + |
| 220 | + return dp[s1.length][s2.length]; |
| 221 | +}; |
| 222 | +``` |
| 223 | + |
| 224 | +## Conclusion |
| 225 | +By utilizing dynamic programming, we can efficiently determine whether a given string `s3` is an interleaving of two other strings `s1` and `s2`. This approach ensures that we consider all possible ways to form `s3` from `s1` and `s2` while adhering to the interleaving constraints. |
0 commit comments