# Find if a string is interleaved of two other strings | DP-33

Given three strings A, B and C. Write a function that checks whether C is an interleaving of A and B. C is said to be interleaving A and B, if it contains all characters of A and B and order of all characters in individual strings is preserved.

**Example:**

Input:strings: "XXXXZY", "XXY", "XXZ"Output:XXXXZY is interleaved of XXY and XXZ The string XXXXZY can be made by interleaving XXY and XXZ String: XXXXZY String 1: XX Y String 2: XX ZInput:strings: "XXY", "YX", "X"Output:XXY is not interleaved of YX and X XXY cannot be formed by interleaving YX and X. The strings that can be formed are YXX and XYX

** Simple Solution:** Recursion.

**Approach:**A simple solution is discussed here:Check whether a given string is an interleaving of two other given string.

The simple solution doesn’t work if the strings A and B have some common characters. For example, let the given string be A and the other strings be B and C. Let A = “XXY”, string B = “XXZ” and string C = “XXZXXXY”. Create a recursive function which takes parameters A, B and C. To handle all cases, two possibilities need to be considered.

- If the first character of C matches with the first character of A, we move one character ahead in A and C and recursively check.
- If the first character of C matches with the first character of B, we move one character ahead in B and C and recursively check.

If any of the above function returns true or A, B and C are empty then return true else return false.

Thanks to Frederic for suggesting this approach.

`// A simple recursive function to check ` `// whether C is an interleaving of A and B ` `bool` `isInterleaved( ` ` ` `char` `* A, ` `char` `* B, ` `char` `* C) ` `{ ` ` ` `// Base Case: If all strings are empty ` ` ` `if` `(!(*A || *B || *C)) ` ` ` `return` `true` `; ` ` ` ` ` `// If C is empty and any of the ` ` ` `// two strings is not empty ` ` ` `if` `(*C == ` `'\0'` `) ` ` ` `return` `false` `; ` ` ` ` ` `// If any of the above mentioned ` ` ` `// two possibilities is true, ` ` ` `// then return true, otherwise false ` ` ` `return` `((*C == *A) && isInterleaved( ` ` ` `A + 1, B, C + 1)) ` ` ` `|| ((*C == *B) && isInterleaved( ` ` ` `A, B + 1, C + 1)); ` `} ` |

*chevron_right*

*filter_none*

**Complexity Analysis:**

**Time Complexity:**O(2^n), where n is the length of the given string.

For every character of the given string there can be 2 options so the time complexity is O(2^n).**Space Complexity:**O(1).

The space complexity is constant.

** Efficient Solution: **Dynamic Programming.

**Approach:**The above recursive solution certainly has many overlapping sub-problems. For example, if wee consider A = “XXX”, B = “XXX” and C = “XXXXXX” and draw recursion tree, there will be many overlapping subproblems. Therefore, like any other typical Dynamic Programming problems, we can solve it by creating a table and store results of sub-problems in a

**bottom-up manner**. For top-down approach of the above solution can be modified by adding a Hash Map.

**Algorithm:**

- Create a DP array (matrix) of size M*N, where m is size of first string and n is the size of second string. Initialize the matrix to false.
- If the sum of sizes of smaller strings is not equal to the size of larger string then return false and break the array as they cant be the interleaved to form the larger string.
- Run a nested loop the outer loop from 0 to m and the inner loop from 0 to n. Loop counters are i and j.
- If the values of i and j are both zeroes then mark dp[i][j] as true. If the value of i is zero and j is non zero and the j-1 character of B is equal to j-1 character of C the assign dp[i][j] as dp[i][j-1] and similarly if j is 0 then match i-1 th character of C and A and if it matches then assign dp[i][j] as dp[i-1][j].
- Take three characters x, y, z as (i-1)th character of A and (j-1)th character of B and (i + j – 1)th character of C.
- if x matches with z and y does not match with z then assign dp[i][j] as dp[i-1][j] similarly if x is not equal to z and y is equal to z then assign dp[i][j] as dp[i][j-1]
- if x is equal to y and y is equal to z then assign dp[i][j] as bitwise OR of dp[i][j-1] and dp[i-1][j].
- return value of dp[m][n].

*Thanks to Abhinav Ramana for suggesting this method of implementation. *

## C++

`// A Dynamic Programming based program ` `// to check whether a string C is ` `// an interleaving of two other ` `// strings A and B. ` `#include <iostream> ` `#include <string.h> ` `using` `namespace` `std; ` ` ` `// The main function that ` `// returns true if C is ` `// an interleaving of A ` `// and B, otherwise false. ` `bool` `isInterleaved( ` ` ` `char` `* A, ` `char` `* B, ` `char` `* C) ` `{ ` ` ` `// Find lengths of the two strings ` ` ` `int` `M = ` `strlen` `(A), N = ` `strlen` `(B); ` ` ` ` ` `// Let us create a 2D table ` ` ` `// to store solutions of ` ` ` `// subproblems. C[i][j] will ` ` ` `// be true if C[0..i+j-1] ` ` ` `// is an interleaving of ` ` ` `// A[0..i-1] and B[0..j-1]. ` ` ` `bool` `IL[M + 1][N + 1]; ` ` ` ` ` `// Initialize all values as false. ` ` ` `memset` `(IL, 0, ` `sizeof` `(IL)); ` ` ` ` ` `// C can be an interleaving of ` ` ` `// A and B only of the sum ` ` ` `// of lengths of A & B is equal ` ` ` `// to the length of C. ` ` ` `if` `((M + N) != ` `strlen` `(C)) ` ` ` `return` `false` `; ` ` ` ` ` `// Process all characters of A and B ` ` ` `for` `(` `int` `i = 0; i <= M; ++i) { ` ` ` `for` `(` `int` `j = 0; j <= N; ++j) { ` ` ` `// two empty strings have an ` ` ` `// empty string as interleaving ` ` ` `if` `(i == 0 && j == 0) ` ` ` `IL[i][j] = ` `true` `; ` ` ` ` ` `// A is empty ` ` ` `else` `if` `(i == 0) { ` ` ` `if` `(B[j - 1] == C[j - 1]) ` ` ` `IL[i][j] = IL[i][j - 1]; ` ` ` `} ` ` ` ` ` `// B is empty ` ` ` `else` `if` `(j == 0) { ` ` ` `if` `(A[i - 1] == C[i - 1]) ` ` ` `IL[i][j] = IL[i - 1][j]; ` ` ` `} ` ` ` ` ` `// Current character of C matches ` ` ` `// with current character of A, ` ` ` `// but doesn't match with current ` ` ` `// character of B ` ` ` `else` `if` `( ` ` ` `A[i - 1] == C[i + j - 1] ` ` ` `&& B[j - 1] != C[i + j - 1]) ` ` ` `IL[i][j] = IL[i - 1][j]; ` ` ` ` ` `// Current character of C matches ` ` ` `// with current character of B, ` ` ` `// but doesn't match with current ` ` ` `// character of A ` ` ` `else` `if` `( ` ` ` `A[i - 1] != C[i + j - 1] ` ` ` `&& B[j - 1] == C[i + j - 1]) ` ` ` `IL[i][j] = IL[i][j - 1]; ` ` ` ` ` `// Current character of C matches ` ` ` `// with that of both A and B ` ` ` `else` `if` `( ` ` ` `A[i - 1] == C[i + j - 1] ` ` ` `&& B[j - 1] == C[i + j - 1]) ` ` ` `IL[i][j] ` ` ` `= (IL[i - 1][j] ` ` ` `|| IL[i][j - 1]); ` ` ` `} ` ` ` `} ` ` ` ` ` `return` `IL[M][N]; ` `} ` ` ` `// A function to run test cases ` `void` `test(` `char` `* A, ` `char` `* B, ` `char` `* C) ` `{ ` ` ` `if` `(isInterleaved(A, B, C)) ` ` ` `cout << C << ` `" is interleaved of "` ` ` `<< A << ` `" and "` `<< B << endl; ` ` ` `else` ` ` `cout << C << ` `" is not interleaved of "` ` ` `<< A << ` `" and "` `<< B << endl; ` `} ` ` ` `// Driver program to test above functions ` `int` `main() ` `{ ` ` ` `test(` `"XXY"` `, ` `"XXZ"` `, ` `"XXZXXXY"` `); ` ` ` `test(` `"XY"` `, ` `"WZ"` `, ` `"WZXY"` `); ` ` ` `test(` `"XY"` `, ` `"X"` `, ` `"XXY"` `); ` ` ` `test(` `"YX"` `, ` `"X"` `, ` `"XXY"` `); ` ` ` `test(` `"XXY"` `, ` `"XXZ"` `, ` `"XXXXZY"` `); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Python3

`# A Dynamic Programming based python3 program ` `# to check whether a string C is an interleaving ` `# of two other strings A and B. ` ` ` `# The main function that returns true if C is ` `# an interleaving of A and B, otherwise false. ` `def` `isInterleaved(A, B, C): ` ` ` ` ` `# Find lengths of the two strings ` ` ` `M ` `=` `len` `(A) ` ` ` `N ` `=` `len` `(B) ` ` ` ` ` `# Let us create a 2D table to store solutions of ` ` ` `# subproblems. C[i][j] will be true if C[0..i + j-1] ` ` ` `# is an interleaving of A[0..i-1] and B[0..j-1]. ` ` ` `# Initialize all values as false. ` ` ` `IL ` `=` `[[` `False` `] ` `*` `(N ` `+` `1` `) ` `for` `i ` `in` `range` `(M ` `+` `1` `)] ` ` ` ` ` `# C can be an interleaving of A and B only of sum ` ` ` `# of lengths of A & B is equal to length of C. ` ` ` `if` `((M ` `+` `N) !` `=` `len` `(C)): ` ` ` `return` `False` ` ` ` ` `# Process all characters of A and B ` ` ` `for` `i ` `in` `range` `(` `0` `, M ` `+` `1` `): ` ` ` `for` `j ` `in` `range` `(` `0` `, N ` `+` `1` `): ` ` ` ` ` `# two empty strings have an empty string ` ` ` `# as interleaving ` ` ` `if` `(i ` `=` `=` `0` `and` `j ` `=` `=` `0` `): ` ` ` `IL[i][j] ` `=` `True` ` ` ` ` `# A is empty ` ` ` `elif` `(i ` `=` `=` `0` `): ` ` ` `if` `(B[j ` `-` `1` `] ` `=` `=` `C[j ` `-` `1` `]): ` ` ` `IL[i][j] ` `=` `IL[i][j ` `-` `1` `] ` ` ` ` ` `# B is empty ` ` ` `elif` `(j ` `=` `=` `0` `): ` ` ` `if` `(A[i ` `-` `1` `] ` `=` `=` `C[i ` `-` `1` `]): ` ` ` `IL[i][j] ` `=` `IL[i ` `-` `1` `][j] ` ` ` ` ` `# Current character of C matches with ` ` ` `# current character of A, but doesn't match ` ` ` `# with current character of B ` ` ` `elif` `(A[i ` `-` `1` `] ` `=` `=` `C[i ` `+` `j ` `-` `1` `] ` `and` ` ` `B[j ` `-` `1` `] !` `=` `C[i ` `+` `j ` `-` `1` `]): ` ` ` `IL[i][j] ` `=` `IL[i ` `-` `1` `][j] ` ` ` ` ` `# Current character of C matches with ` ` ` `# current character of B, but doesn't match ` ` ` `# with current character of A ` ` ` `elif` `(A[i ` `-` `1` `] !` `=` `C[i ` `+` `j ` `-` `1` `] ` `and` ` ` `B[j ` `-` `1` `] ` `=` `=` `C[i ` `+` `j ` `-` `1` `]): ` ` ` `IL[i][j] ` `=` `IL[i][j ` `-` `1` `] ` ` ` ` ` `# Current character of C matches with ` ` ` `# that of both A and B ` ` ` `elif` `(A[i ` `-` `1` `] ` `=` `=` `C[i ` `+` `j ` `-` `1` `] ` `and` ` ` `B[j ` `-` `1` `] ` `=` `=` `C[i ` `+` `j ` `-` `1` `]): ` ` ` `IL[i][j] ` `=` `(IL[i ` `-` `1` `][j] ` `or` `IL[i][j ` `-` `1` `]) ` ` ` ` ` `return` `IL[M][N] ` ` ` `# A function to run test cases ` `def` `test(A, B, C): ` ` ` ` ` `if` `(isInterleaved(A, B, C)): ` ` ` `print` `(C, ` `"is interleaved of"` `, A, ` `"and"` `, B) ` ` ` `else` `: ` ` ` `print` `(C, ` `"is not interleaved of"` `, A, ` `"and"` `, B) ` ` ` `# Driver Code ` `if` `__name__ ` `=` `=` `'__main__'` `: ` ` ` `test(` `"XXY"` `, ` `"XXZ"` `, ` `"XXZXXXY"` `) ` ` ` `test(` `"XY"` `, ` `"WZ"` `, ` `"WZXY"` `) ` ` ` `test(` `"XY"` `, ` `"X"` `, ` `"XXY"` `) ` ` ` `test(` `"YX"` `, ` `"X"` `, ` `"XXY"` `) ` ` ` `test(` `"XXY"` `, ` `"XXZ"` `, ` `"XXXXZY"` `) ` ` ` `# This code is contributed by ashutosh450 ` |

*chevron_right*

*filter_none*

Output:

XXZXXXY is not interleaved of XXY and XXZ WZXY is interleaved of XY and WZ XXY is interleaved of XY and X XXY is not interleaved of YX and X XXXXZY is interleaved of XXY and XXZ

See this for more test cases.

**Complexity Analysis:**

**Time Complexity:**O(M*N).

Since a traversal of DP array is needed, so the time Complexity is O(M*N).**Space Complexity:**O(M*N).

This is the space required to store the DP array.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: **DSA Self Paced**. Become industry ready at a student-friendly price.

## Recommended Posts:

- Given a string and an integer k, find the kth sub-string when all the sub-strings are sorted according to the given condition
- Find all palindromic sub-strings of a given string | Set 2
- Given two strings, find if first string is a subsequence of second
- Find all distinct palindromic sub-strings of a given string
- Find a string in lexicographic order which is in between given two strings
- Find the longest string that can be made up of other strings from the array
- Find the number of strings formed using distinct characters of a given string
- Meta Strings (Check if two strings can become same after a swap in one string)
- Number of sub-strings which are anagram of any sub-string of another string
- Longest string which is prefix string of at least two strings
- Sub-strings of a string that are prefix of the same string
- Count All Palindrome Sub-Strings in a String | Set 1
- Different substrings in a string that start and end with given strings
- Frequency of a string in an array of strings
- Strings from an array which are not prefix of any other string
- All possible strings of any length that can be formed from a given string
- String from prefix and suffix of given two strings
- String matching with * (that matches with any) in any of the two strings
- Count All Palindrome Sub-Strings in a String | Set 2
- Count of sub-strings of length n possible from the given string