Skip to content

Commit d58caad

Browse files
committed
Three-Hundred-Thirteen Commit: Add Strings Interleaving problem to Longest Common Substring section
1 parent feb3674 commit d58caad

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package Dynamic_Programming.Longest_Common_SubString;
2+
3+
// Problem Statement: Strings Interleaving
4+
// LeetCode Question: 97. Interleaving String
5+
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
public class Problem_13_String_Interleaving {
10+
// Brute Force Approach
11+
public boolean findSI(String m, String n, String p) {
12+
return findSIRecursive(m, n, p, 0, 0, 0);
13+
}
14+
15+
private boolean findSIRecursive(String m, String n, String p, int mIndex, int nIndex, int pIndex) {
16+
17+
// if we have reached the end of the all the strings
18+
if(mIndex == m.length() && nIndex == n.length() && pIndex == p.length())
19+
return true;
20+
21+
// if we have reached the end of 'p' but 'm' or 'n' still have some characters left
22+
if(pIndex == p.length())
23+
return false;
24+
25+
boolean b1=false, b2=false;
26+
if(mIndex < m.length() && m.charAt(mIndex) == p.charAt(pIndex))
27+
b1 = findSIRecursive(m, n, p, mIndex+1, nIndex, pIndex+1);
28+
29+
if(nIndex < n.length() && n.charAt(nIndex) == p.charAt(pIndex))
30+
b2 = findSIRecursive(m, n, p, mIndex, nIndex+1, pIndex+1);
31+
32+
return b1 || b2;
33+
}
34+
35+
// Top-down Dynamic Programming with Memoization Approach
36+
public Boolean findSI_1(String m, String n, String p) {
37+
Map<String, Boolean> dp = new HashMap<>();
38+
return findSIRecursive(dp, m, n, p, 0, 0, 0);
39+
}
40+
41+
private boolean findSIRecursive(Map<String, Boolean> dp, String m, String n, String p,
42+
int mIndex, int nIndex, int pIndex) {
43+
44+
// if we have reached the end of the all the strings
45+
if(mIndex == m.length() && nIndex == n.length() && pIndex == p.length())
46+
return true;
47+
48+
// if we have reached the end of 'p' but 'm' or 'n' still has some characters left
49+
if(pIndex == p.length())
50+
return false;
51+
52+
String subProblemKey = mIndex + "-" + nIndex + "-" + pIndex;
53+
if(!dp.containsKey(subProblemKey)) {
54+
boolean b1=false, b2=false;
55+
if(mIndex < m.length() && m.charAt(mIndex) == p.charAt(pIndex))
56+
b1 = findSIRecursive(dp, m, n, p, mIndex+1, nIndex, pIndex+1);
57+
58+
if(nIndex < n.length() && n.charAt(nIndex) == p.charAt(pIndex))
59+
b2 = findSIRecursive(dp, m, n, p, mIndex, nIndex+1, pIndex+1);
60+
61+
dp.put(subProblemKey, b1 || b2);
62+
}
63+
64+
return dp.get(subProblemKey);
65+
}
66+
67+
// Bottom-up Dynamic Programming Approach
68+
public Boolean findSI_2(String m, String n, String p) {
69+
// dp[mIndex][nIndex] will be storing the result of string interleaving
70+
// up to p[0..mIndex+nIndex-1]
71+
boolean[][] dp = new boolean[m.length()+1][n.length()+1];
72+
73+
// make sure if lengths of the strings add up
74+
if(m.length() + n.length() != p.length())
75+
return false;
76+
77+
for(int mIndex=0; mIndex<=m.length(); mIndex++) {
78+
for(int nIndex=0; nIndex<=n.length(); nIndex++) {
79+
// if 'm' and 'n' are empty, then 'p' must have been empty too.
80+
if(mIndex==0 && nIndex==0)
81+
dp[mIndex][nIndex] = true;
82+
// if 'm' is empty, we need to check the interleaving with 'n' only
83+
else if (mIndex==0 && n.charAt(nIndex-1) == p.charAt(mIndex+nIndex-1))
84+
dp[mIndex][nIndex] = dp[mIndex][nIndex-1];
85+
// if 'n' is empty, we need to check the interleaving with 'm' only
86+
else if (nIndex==0 && m.charAt(mIndex-1) == p.charAt(mIndex+nIndex-1))
87+
dp[mIndex][nIndex] = dp[mIndex-1][nIndex];
88+
else {
89+
// if the letter of 'm' and 'p' match, we take whatever is matched till mIndex-1
90+
if(mIndex > 0 && m.charAt(mIndex-1) == p.charAt(mIndex+nIndex-1))
91+
dp[mIndex][nIndex] = dp[mIndex-1][nIndex];
92+
// if the letter of 'n' and 'p' match, we take whatever is matched till nIndex-1 too
93+
// note the '|=', this is required when we have common letters
94+
if(nIndex > 0 && n.charAt(nIndex-1) == p.charAt(mIndex+nIndex-1))
95+
dp[mIndex][nIndex] |= dp[mIndex][nIndex-1];
96+
}
97+
}
98+
}
99+
return dp[m.length()][n.length()];
100+
}
101+
}

0 commit comments

Comments
 (0)