Skip to content

Commit

Permalink
Solved LeetCode Interleaving Strings Problem
Browse files Browse the repository at this point in the history
  • Loading branch information
ghsatpute committed Apr 24, 2023
1 parent 8d88835 commit 67eabb2
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package problemsolving.leetcode.algorithm.dynamicProgramming.interleavingStrings;

public class InterleavingStringsBruteForce {
String s1, s2, s3;
public boolean isInterleave(String s1, String s2, String s3) {
if ((s1.length() == 0 || s2.length() == 0) && s3.length() == 0) {
return true;
}
this.s1 = s1;
this.s2 = s2;
this.s3 = s3;

return isInterleave(0, 0, 0);
}

private boolean isInterleave(int index1, int index2, int index3) {
// If last character to be matched is in string 1
if (index1 == s1.length() - 1 && index2 == s2.length() && index3 == s3.length() - 1) {
return s1.charAt(index1) == s3.charAt(index3);
}

// If last character to be matched is in string 2
if (index1 == s1.length() && index2 == s2.length() - 1 && index3 == s3.length() - 1) {
return s2.charAt(index2) == s3.charAt(index3);
}

// In any other case, if index is bigger than any index return false;
if (index1 > s1.length() || index2 > s2.length() || index3 >= s3.length()) {
return false;
}

boolean s1CharMatching = false, s2CharMatching = false;

// Try to match character from s1, if index1 is less than length of string
if (index1 < s1.length() && s1.charAt(index1) == s3.charAt(index3)) {
s1CharMatching = isInterleave(index1 + 1, index2, index3 + 1);
}

// Try matching character from s2, if index2 is less than length of string
if (index2 < s2.length() && s2.charAt(index2) == s3.charAt(index3)) {
s2CharMatching = isInterleave(index1, index2 + 1, index3 + 1);
}

return s1CharMatching || s2CharMatching;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package problemsolving.leetcode.algorithm.dynamicProgramming.interleavingStrings;

public class InterleavingStringsDynamicProgramming {
String s1, s2, s3;
Boolean[][] dp;
public boolean isInterleave(String s1, String s2, String s3) {
if ((s1.length() == 0 || s2.length() == 0) && s3.length() == 0) {
return true;
}
this.s1 = s1;
this.s2 = s2;
this.s3 = s3;
this.dp = new Boolean[s1.length() + 1][s2.length() + 1];

return isInterleave(0, 0, 0);
}

private boolean isInterleave(int index1, int index2, int index3) {
// If last character to be matched is in string 1
if (index1 == s1.length() - 1 && index2 == s2.length() && index3 == s3.length() - 1) {
return s1.charAt(index1) == s3.charAt(index3);
}

// If last character to be matched is in string 2
if (index1 == s1.length() && index2 == s2.length() - 1 && index3 == s3.length() - 1) {
return s2.charAt(index2) == s3.charAt(index3);
}

if (dp[index1][index2] != null) {
return dp[index1][index2];
}

// In any other case, if index is bigger than any index return false;
if (index1 > s1.length() || index2 > s2.length() || index3 >= s3.length()) {
return false;
}

boolean s1CharMatching = false, s2CharMatching = false;

// Try to match character from s1, if index1 is less than length of string
if (index1 < s1.length() && s1.charAt(index1) == s3.charAt(index3)) {
s1CharMatching = isInterleave(index1 + 1, index2, index3 + 1);
}

// Try matching character from s2, if index2 is less than length of string
if (index2 < s2.length() && s2.charAt(index2) == s3.charAt(index3)) {
s2CharMatching = isInterleave(index1, index2 + 1, index3 + 1);
}

dp[index1][index2] = s1CharMatching || s2CharMatching;

return s1CharMatching || s2CharMatching;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 97. Interleaving String

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`
* The interleaving is `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
![Example1.png](Example1.png)
```
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.

# Solution Reference
https://www.youtube.com/watch?v=3Rw3p9LrgvE&ab_channel=NeetCode
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package problemsolving.leetcode.algorithm.dynamicProgramming.interleavingStrings;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

class InterleavingStringsBruteForceTest {
@Test
public void testCase01() {
String string1 = "aabcc";
String string2 = "dbbca";
String string3 = "aadbbcbcac";

boolean output = new InterleavingStringsBruteForce().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
public void testCase02() {
String string1 = "aabcc";
String string2 = "dbbca";
String string3 = "aadbbbaccc";

boolean output = new InterleavingStringsBruteForce().isInterleave(string1, string2, string3);

assertFalse(output);
}

@Test
public void testCase03() {
String string1 = "";
String string2 = "";
String string3 = "";

boolean output = new InterleavingStringsBruteForce().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
public void testCase04() {
String string1 = "abc";
String string2 = "";
String string3 = "";

boolean output = new InterleavingStringsBruteForce().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
public void testCase05() {
String string1 = "aa";
String string2 = "ab";
String string3 = "abaa";

boolean output = new InterleavingStringsBruteForce().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
@Disabled("This test takes 52 seconds to run. See DP solution to solve it")
public void testCase06() {
String string1 = "aaaaaaaaaaaaaaaaa";
String string2 = "aaaaaaaaaaaaaaaaa";
String string3 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

boolean output = new InterleavingStringsBruteForce().isInterleave(string1, string2, string3);

assertTrue(output);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package problemsolving.leetcode.algorithm.dynamicProgramming.interleavingStrings;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class InterleavingStringsDynamicProgrammingTest {
@Test
public void testCase01() {
String string1 = "aabcc";
String string2 = "dbbca";
String string3 = "aadbbcbcac";

boolean output = new InterleavingStringsDynamicProgramming().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
public void testCase02() {
String string1 = "aabcc";
String string2 = "dbbca";
String string3 = "aadbbbaccc";

boolean output = new InterleavingStringsDynamicProgramming().isInterleave(string1, string2, string3);

assertFalse(output);
}

@Test
public void testCase03() {
String string1 = "";
String string2 = "";
String string3 = "";

boolean output = new InterleavingStringsDynamicProgramming().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
public void testCase04() {
String string1 = "abc";
String string2 = "";
String string3 = "";

boolean output = new InterleavingStringsDynamicProgramming().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
public void testCase05() {
String string1 = "aa";
String string2 = "ab";
String string3 = "abaa";

boolean output = new InterleavingStringsDynamicProgramming().isInterleave(string1, string2, string3);

assertTrue(output);
}

@Test
public void testCase06() {
// This test used to take ~52 seconds in brute force, now takes 1ms
String string1 = "aaaaaaaaaaaaaaaaa";
String string2 = "aaaaaaaaaaaaaaaaa";
String string3 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

boolean output = new InterleavingStringsDynamicProgramming().isInterleave(string1, string2, string3);

assertTrue(output);
}
}

0 comments on commit 67eabb2

Please sign in to comment.