Check if a String is Interleaving of Other Two
Last Updated :
23 Jul, 2025
Give three strings s1, s2 and s3, determine if s3 is formed by interleaving s1 and s2.
A string s3
is an interleaving of s1
and s2
if:
- It contains all characters of
s1
and s2
while preserving their relative order. - Characters from
s1
and s2
appear in s3
in the same order as in their original strings. - The length of
s3
equals the combined length of s1
and s2
.
Example
Input: s1 = "AAB", s2 = "AAC", s3 = "AAAABC",
Output: true
Explanation: The string "AAAABC" has all characters of the other two strings and in the same order.
Input: s1 = "AB", s2 = "C", s3 = "ACB",
Output: true
Explanation: s3 has all characters of s1 and s2 and retains order of characters of s1.
Input: s1 = "YX", s2 = "X", s3 = "XXY"
Output: false
Explanation: "XXY " is not interleaved of "YX" and "X". The strings that can be formed are YXX and XYX
[Naive Approach] Using Recursion - O(2^(m+n)) Time and O(m+n) Space
The main idea is to recursively check whether s3 can be formed by choosing characters from s1 and s2, ensuring we maintain the correct order. To do so, initialise three variable i, j, and k to store the index of string s1, s2, and s3 respectively. To handle all cases, the following possibilities need to be considered.
- If the first character of s3 matches the first character of s1, we move one character ahead in s1 and s3 and recursively check.
- If the first character of s3 matches the first character of s2, we move one character ahead in s2 and s3 and recursively check.
- If none of the two characters match, return false.
- If any of the above function returns true or s1, s2 and s3 are empty then return true else return false.
C++
// Cpp program to check if Check if a String is
// Interleaving of Other Two using recursion
#include <iostream>
using namespace std;
// i amnd j are indexes in s1 and s2 respectively
bool isILRec(string &s1, string &s2, string &s3, int i, int j)
{
int k = i + j;
// If all strings are fully traversed
if (i == s1.size() && j == s2.size() && k == s3.size())
return true;
// If any of the above mentioned two
// possibilities then return true
// otherwise return false.
bool a = (i < s1.size()) && (s3[k] == s1[i]) && isILRec(s1, s2, s3, i + 1, j);
bool b = (j < s2.size()) && (s3[k] == s2[j]) && isILRec(s1, s2, s3, i, j + 1);
return a || b;
}
bool isInterleave(string &s1, string &s2, string &s3)
{
// A basic condition that must be ensured
if (s1.size() + s2.size() != s3.size())
return false;
return isILRec(s1, s2, s3, 0, 0);
}
int main()
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
cout << (isInterleave(s1, s2, s3) ? "true" : "false") << endl;
return 0;
}
Java
// Java program to check if Check if a String is
// Interleaving of Other Two using recursion
class GfG {
// i and j are indexes in s1 and s2 respectively
static boolean isILRec(String s1, String s2, String s3,
int i, int j)
{
int k = i + j;
// If all strings are fully traversed
if (i == s1.length() && j == s2.length()
&& k == s3.length())
return true;
// If any of the above mentioned two
// possibilities then return true
// otherwise return false.
boolean a = (i < s1.length())
&& (s3.charAt(k) == s1.charAt(i))
&& isILRec(s1, s2, s3, i + 1, j);
boolean b = (j < s2.length())
&& (s3.charAt(k) == s2.charAt(j))
&& isILRec(s1, s2, s3, i, j + 1);
return a || b;
}
static boolean isInterleave(String s1, String s2,
String s3)
{
// A basic condition that must be ensured
if (s1.length() + s2.length() != s3.length())
return false;
return isILRec(s1, s2, s3, 0, 0);
}
public static void main(String[] args)
{
String s1 = "AAB";
String s2 = "AAC";
String s3 = "AAAABC";
System.out.println(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
Python
# Python program to check if Check if a String is
# Interleaving of Other Two using recursion
def isILRec(s1, s2, s3, i, j):
# i and j are indexes in s1 and s2 respectively
k = i + j
# If all strings are fully traversed
if i == len(s1) and j == len(s2) and k == len(s3):
return True
# If any of the above mentioned two
# possibilities then return true
# otherwise return false.
a = (i < len(s1)) and (s3[k] == s1[i]) and isILRec(s1, s2, s3, i + 1, j)
b = (j < len(s2)) and (s3[k] == s2[j]) and isILRec(s1, s2, s3, i, j + 1)
return a or b
def isInterleave(s1, s2, s3):
# A basic condition that must be ensured
if len(s1) + len(s2) != len(s3):
return False
return isILRec(s1, s2, s3, 0, 0)
if __name__ == "__main__":
s1 = "AAB"
s2 = "AAC"
s3 = "AAAABC"
print("true" if isInterleave(s1, s2, s3) else "false")
C#
// C# program to check if Check if a String is
// Interleaving of Other Two using recursion
using System;
class GfG {
// i and j are indexes in s1 and s2 respectively
static bool isILRec(string s1, string s2, string s3,
int i, int j)
{
int k = i + j;
// If all strings are fully traversed
if (i == s1.Length && j == s2.Length
&& k == s3.Length)
return true;
// If any of the above mentioned two
// possibilities then return true
// otherwise return false.
bool a = (i < s1.Length) && (s3[k] == s1[i])
&& isILRec(s1, s2, s3, i + 1, j);
bool b = (j < s2.Length) && (s3[k] == s2[j])
&& isILRec(s1, s2, s3, i, j + 1);
return a || b;
}
static bool isInterleave(string s1, string s2,
string s3)
{
// A basic condition that must be ensured
if (s1.Length + s2.Length != s3.Length)
return false;
return isILRec(s1, s2, s3, 0, 0);
}
static void Main(string[] args)
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
Console.WriteLine(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
JavaScript
// JavaScript program to check if Check if a String is
// Interleaving of Other Two using recursion
function isILRec(s1, s2, s3, i, j)
{
// i and j are indexes in s1 and s2 respectively
let k = i + j;
// If all strings are fully traversed
if (i === s1.length && j === s2.length
&& k === s3.length)
return true;
// If any of the above mentioned two
// possibilities then return true
// otherwise return false.
let a = (i < s1.length) && (s3[k] === s1[i])
&& isILRec(s1, s2, s3, i + 1, j);
let b = (j < s2.length) && (s3[k] === s2[j])
&& isILRec(s1, s2, s3, i, j + 1);
return a || b;
}
function isInterleave(s1, s2, s3)
{
// A basic condition that must be ensured
if (s1.length + s2.length !== s3.length)
return false;
return isILRec(s1, s2, s3, 0, 0);
}
// Driver Code
let s1 = "AAB";
let s2 = "AAC";
let s3 = "AAAABC";
console.log(isInterleave(s1, s2, s3) ? "true" : "false");
[Better Approach 1] Using Top-Down DP - O(m*n) Time and O(n*m) Space
The above recursive solution certainly has many overlapping sub-problems. For example, if we consider s1 = "AAB”, s2 = “AAC” and s3 = “AAAABC” and draw a 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. Below is a memoization based solution that creates a 2D memo array.
We optimize the recursive approach using memoization to avoid redundant calculations.
We track indices i and j in s1 and s2, respectively, ensuring that characters match s3 at index k = i + j. If either s1[i] or s2[j] matches s3[k], we recursively move forward while storing results in a memo table to prevent recomputation.
The base case ensures that when all strings are fully traversed, we return true. This approach significantly reduces the time complexity compared to plain recursion.
Steps to implement the above idea:
- Check if s3 length is equal to s1 + s2, return false if not.
- Create a (m+1) x (n+1) table memo[][] with -1 to store results. The value of memo[i][j] is going to be 1 if s3[0..i + j-1] is an interleaving of s1[0..i-1] and s2[0..j-1], else 0.
- If memo[i][j] is not -1, return the stored result to avoid recomputation.
- Try both possibilities (matching s1[i] or s2[j] with s3[k]) and store the result in memo[i][j].
- Return true if all strings are fully traversed, otherwise return false.
C++
// C++ program to check if Check if a String is
// Interleaving of Other Two using memoization
#include <bits/stdc++.h>
using namespace std;
bool isILRec(string &s1, string &s2, string &s3, int i, int j, vector<vector<int>> &memo)
{
int k = i + j;
int m = s1.size(), n = s2.size();
// Base case: If all strings are fully traversed
if (i == m && j == n && k == s3.size())
return true;
// If we have already solved this subproblem,
// return the stored result
if (memo[i][j] != -1)
{
return memo[i][j];
}
// Check if next characcter of s1 maatchs with
// with the next one of s3
bool a = (i < m && s1[i] == s3[k]) && isILRec(s1, s2, s3, i + 1, j, memo);
// Check if next characcter of s2 maatchs with
// with the next one of s3
bool b = (j < n && s2[j] == s3[k]) && isILRec(s1, s2, s3, i, j + 1, memo);
return memo[i][j] = a || b;
}
bool isInterleave(string &s1, string &s2, string &s3)
{
int m = s1.size(), n = s2.size();
// A basic condition that must be ensured
if (m + n != s3.size())
return false;
// Intiialize memo with -1 and make Recursive function call
vector<vector<int>> memo(m + 1, vector<int>(n + 1, -1));
return isILRec(s1, s2, s3, 0, 0, memo);
}
int main()
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
cout << (isInterleave(s1, s2, s3) ? "true" : "false") << endl;
return 0;
}
Java
// Java program to check if Check if a String is
// Interleaving of Other Two using memoization
import java.util.Arrays;
class GfG {
// i and j are indexes in s1 and s2 respectively
static boolean isILRec(String s1, String s2, String s3,
int i, int j, int[][] memo)
{
int k = i + j;
int m = s1.length();
int n = s2.length();
// Base case: If all strings are fully traversed
if (i == m && j == n && k == s3.length())
return true;
// If we have already solved this subproblem,
// return the stored result
if (memo[i][j] != -1) {
return memo[i][j] == 1;
}
// Check if next character of s1 matches with
// with the next one of s3
boolean a = false;
if (i < m && s1.charAt(i) == s3.charAt(k)) {
a = isILRec(s1, s2, s3, i + 1, j, memo);
}
// Check if next character of s2 matches with
// with the next one of s3
boolean b = false;
if (j < n && s2.charAt(j) == s3.charAt(k)) {
b = isILRec(s1, s2, s3, i, j + 1, memo);
}
memo[i][j] = a || b ? 1 : 0;
return a || b;
}
static boolean isInterleave(String s1, String s2,
String s3)
{
int m = s1.length();
int n = s2.length();
// A basic condition that must be ensured
if (m + n != s3.length())
return false;
// Initialize memo with -1 and make Recursive
// function call
int[][] memo = new int[m + 1][n + 1];
for (int[] row : memo)
Arrays.fill(row, -1);
return isILRec(s1, s2, s3, 0, 0, memo);
}
public static void main(String[] args)
{
String s1 = "AAB";
String s2 = "AAC";
String s3 = "AAAABC";
System.out.println(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
Python
# Python program to check if Check if a String is
# Interleaving of Other Two using memoization
def isILRec(s1, s2, s3, i, j, memo):
# i and j are indexes in s1 and s2 respectively
k = i + j
m = len(s1)
n = len(s2)
# Base case: If all strings are fully traversed
if i == m and j == n and k == len(s3):
return True
# If we have already solved this subproblem,
# return the stored result
if memo[i][j] != -1:
return memo[i][j] == 1
# Check if next character of s1 matches with
# with the next one of s3
a = False
if i < m and s1[i] == s3[k]:
a = isILRec(s1, s2, s3, i + 1, j, memo)
# Check if next character of s2 matches with
# with the next one of s3
b = False
if j < n and s2[j] == s3[k]:
b = isILRec(s1, s2, s3, i, j + 1, memo)
memo[i][j] = 1 if a or b else 0
return a or b
def isInterleave(s1, s2, s3):
# A basic condition that must be ensured
m = len(s1)
n = len(s2)
if m + n != len(s3):
return False
# Initialize memo with -1 and make Recursive function call
memo = [[-1 for _ in range(n + 1)] for _ in range(m + 1)]
return isILRec(s1, s2, s3, 0, 0, memo)
if __name__ == "__main__":
s1 = "AAB"
s2 = "AAC"
s3 = "AAAABC"
print("true" if isInterleave(s1, s2, s3) else "false")
C#
// C# program to check if Check if a String is
// Interleaving of Other Two using memoization
using System;
class GfG {
// i and j are indexes in s1 and s2 respectively
static bool isILRec(string s1, string s2, string s3,
int i, int j, int[, ] memo)
{
int k = i + j;
int m = s1.Length;
int n = s2.Length;
// Base case: If all strings are fully traversed
if (i == m && j == n && k == s3.Length)
return true;
// If we have already solved this subproblem,
// return the stored result
if (memo[i, j] != -1)
return memo[i, j] == 1;
// Check if next character of s1 matches with
// with the next one of s3
bool a = false;
if (i < m && s1[i] == s3[k])
a = isILRec(s1, s2, s3, i + 1, j, memo);
// Check if next character of s2 matches with
// with the next one of s3
bool b = false;
if (j < n && s2[j] == s3[k])
b = isILRec(s1, s2, s3, i, j + 1, memo);
memo[i, j] = (a || b) ? 1 : 0;
return a || b;
}
static bool isInterleave(string s1, string s2,
string s3)
{
int m = s1.Length;
int n = s2.Length;
// A basic condition that must be ensured
if (m + n != s3.Length)
return false;
// Initialize memo with -1 and make Recursive
// function call
int[, ] memo = new int[m + 1, n + 1];
for (int i = 0; i <= m; i++)
for (int j = 0; j <= n; j++)
memo[i, j] = -1;
return isILRec(s1, s2, s3, 0, 0, memo);
}
static void Main(string[] args)
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
Console.WriteLine(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
JavaScript
// Javascript program to check if Check if a String is
// Interleaving of Other Two using memoization
function isILRec(s1, s2, s3, i, j, memo)
{
// i and j are indexes in s1 and s2 respectively
let k = i + j;
let m = s1.length;
let n = s2.length;
// Base case: If all strings are fully traversed
if (i === m && j === n && k === s3.length)
return true;
// If we have already solved this subproblem,
// return the stored result
if (memo[i][j] !== -1) {
return memo[i][j] === 1;
}
// Check if next character of s1 matches with
// with the next one of s3
let a = false;
if (i < m && s1[i] === s3[k]) {
a = isILRec(s1, s2, s3, i + 1, j, memo);
}
// Check if next character of s2 matches with
// with the next one of s3
let b = false;
if (j < n && s2[j] === s3[k]) {
b = isILRec(s1, s2, s3, i, j + 1, memo);
}
memo[i][j] = (a || b) ? 1 : 0;
return a || b;
}
function isInterleave(s1, s2, s3)
{
// A basic condition that must be ensured
let m = s1.length;
let n = s2.length;
if (m + n !== s3.length)
return false;
// Initialize memo with -1 and make Recursive function
// call
let memo = Array(m + 1).fill(null).map(
() => Array(n + 1).fill(-1));
return isILRec(s1, s2, s3, 0, 0, memo);
}
// Driver Code
let s1 = "AAB";
let s2 = "AAC";
let s3 = "AAAABC";
console.log(isInterleave(s1, s2, s3) ? "true" : "false");
[Better Approach 2] Using Bottom-Up DP - O(m*n) Time and O(m*n) Space
Step by Step implementation:
- The main idea is to create a 2D DP table dp[m+1][n+1] , where dp[i][j] represents whether s3[0...i+j-1] is an interleaving of s1[0...i-1] and s2[0...j-1].
- dp[0][0] = true, because an empty s1 and s2 can form an empty s3.
- Fill the First Row and First Column
- If s1 is empty, we can only form s3 by taking characters from s2.
- If s2 is empty, we can only form s3 by taking characters from s1.
- The DP formula checks whether s3[k] (where k = i + j) matches either:
- The current character of s1 (s1[i-1]), while ensuring that the previous part dp[i-1][j] is true.
- The current character of s2 (s2[j-1]), while ensuring that the previous part dp[i][j-1] is true.
- The DP table is filled iteratively until dp[m][n] contains the answer.
C++
// C++ program to check if Check if a String is Interleaving
// of Other Two using Dynamic Programming
#include <bits/stdc++.h>
using namespace std;
// The main function that
// returns true if s3 is
// an interleaving of s1
// and s2, otherwise false.
bool isInterleave(string &s1, string &s2, string &s3)
{
int m = s1.size(), n = s2.size();
// s3 can be an interleaving of s1 and s2 only if
// the sum of lengths of s1 & s2 is equal to the length of s3.
if (m + n != s3.size())
return false;
vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
// Handle the corner case where both s1 and s2 are empty
dp[0][0] = true;
// Fill the first row (when s1 is empty)
for (int j = 1; j <= n; ++j)
{
dp[0][j] = (s2[j - 1] == s3[j - 1]) && dp[0][j - 1];
}
// Fill the first column (when s2 is empty)
for (int i = 1; i <= m; ++i)
{
dp[i][0] = (s1[i - 1] == s3[i - 1]) && dp[i - 1][0];
}
// Process all characters of s1 and s2
for (int i = 1; i <= m; ++i)
{
for (int j = 1; j <= n; ++j)
{
int k = i + j;
dp[i][j] = (s1[i - 1] == s3[k - 1] && dp[i - 1][j]) || (s2[j - 1] == s3[k - 1] && dp[i][j - 1]);
}
}
return dp[m][n];
}
int main()
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
cout << (isInterleave(s1, s2, s3) ? "true" : "false") << endl;
return 0;
}
Java
// Java program to check if a String is Interleaving
// of Other Two using Dynamic Programming
import java.util.Arrays;
class GfG {
// The main function that
// returns true if s3 is
// an interleaving of s1
// and s2, otherwise false.
static boolean isInterleave(String s1, String s2,
String s3)
{
int m = s1.length();
int n = s2.length();
// s3 can be an interleaving of s1 and s2 only if
// the sum of lengths of s1 & s2 is equal to the
// length of s3.
if (m + n != s3.length())
return false;
boolean[][] dp = new boolean[m + 1][n + 1];
// Handle the corner case where both s1 and s2 are
// empty
dp[0][0] = true;
// Fill the first row (when s1 is empty)
for (int j = 1; j <= n; ++j) {
dp[0][j]
= (s2.charAt(j - 1) == s3.charAt(j - 1))
&& dp[0][j - 1];
}
// Fill the first column (when s2 is empty)
for (int i = 1; i <= m; ++i) {
dp[i][0]
= (s1.charAt(i - 1) == s3.charAt(i - 1))
&& dp[i - 1][0];
}
// Process all characters of s1 and s2
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
int k = i + j;
dp[i][j]
= (s1.charAt(i - 1) == s3.charAt(k - 1)
&& dp[i - 1][j])
|| (s2.charAt(j - 1)
== s3.charAt(k - 1)
&& dp[i][j - 1]);
}
}
return dp[m][n];
}
public static void main(String[] args)
{
String s1 = "AAB";
String s2 = "AAC";
String s3 = "AAAABC";
System.out.println(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
Python
# Python program to check if a String is Interleaving
# of Other Two using Dynamic Programming
def isInterleave(s1, s2, s3):
# The main function that
# returns true if s3 is
# an interleaving of s1
# and s2, otherwise false.
m = len(s1)
n = len(s2)
# s3 can be an interleaving of s1 and s2 only if
# the sum of lengths of s1 & s2 is equal to the length of s3.
if m + n != len(s3):
return False
dp = [[False] * (n + 1) for _ in range(m + 1)]
# Handle the corner case where both s1 and s2 are empty
dp[0][0] = True
# Fill the first row (when s1 is empty)
for j in range(1, n + 1):
dp[0][j] = (s2[j - 1] == s3[j - 1]) and dp[0][j - 1]
# Fill the first column (when s2 is empty)
for i in range(1, m + 1):
dp[i][0] = (s1[i - 1] == s3[i - 1]) and dp[i - 1][0]
# Process all characters of s1 and s2
for i in range(1, m + 1):
for j in range(1, n + 1):
k = i + j
dp[i][j] = (s1[i - 1] == s3[k - 1] and dp[i - 1][j]) or \
(s2[j - 1] == s3[k - 1] and dp[i][j - 1])
return dp[m][n]
if __name__ == "__main__":
s1 = "AAB"
s2 = "AAC"
s3 = "AAAABC"
print("true" if isInterleave(s1, s2, s3) else "false")
C#
// C# program to check if a String is Interleaving
// of Other Two using Dynamic Programming
using System;
class GfG {
// The main function that
// returns true if s3 is
// an interleaving of s1
// and s2, otherwise false.
static bool isInterleave(string s1, string s2,
string s3)
{
int m = s1.Length;
int n = s2.Length;
// s3 can be an interleaving of s1 and s2 only if
// the sum of lengths of s1 & s2 is equal to the
// length of s3.
if (m + n != s3.Length)
return false;
bool[, ] dp = new bool[m + 1, n + 1];
// Handle the corner case where both s1 and s2 are
// empty
dp[0, 0] = true;
// Fill the first row (when s1 is empty)
for (int j = 1; j <= n; ++j) {
dp[0, j]
= (s2[j - 1] == s3[j - 1]) && dp[0, j - 1];
}
// Fill the first column (when s2 is empty)
for (int i = 1; i <= m; ++i) {
dp[i, 0]
= (s1[i - 1] == s3[i - 1]) && dp[i - 1, 0];
}
// Process all characters of s1 and s2
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
int k = i + j;
dp[i, j] = (s1[i - 1] == s3[k - 1]
&& dp[i - 1, j])
|| (s2[j - 1] == s3[k - 1]
&& dp[i, j - 1]);
}
}
return dp[m, n];
}
static void Main(string[] args)
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
Console.WriteLine(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
JavaScript
// JavaScript program to check if a String is Interleaving
// of Other Two using Dynamic Programming
function isInterleave(s1, s2, s3)
{
// The main function that
// returns true if s3 is
// an interleaving of s1
// and s2, otherwise false.
let m = s1.length;
let n = s2.length;
// s3 can be an interleaving of s1 and s2 only if
// the sum of lengths of s1 & s2 is equal to the length
// of s3.
if (m + n !== s3.length)
return false;
let dp = Array(m + 1).fill(null).map(
() => Array(n + 1).fill(false));
// Handle the corner case where both s1 and s2 are empty
dp[0][0] = true;
// Fill the first row (when s1 is empty)
for (let j = 1; j <= n; ++j) {
dp[0][j]
= (s2[j - 1] === s3[j - 1]) && dp[0][j - 1];
}
// Fill the first column (when s2 is empty)
for (let i = 1; i <= m; ++i) {
dp[i][0]
= (s1[i - 1] === s3[i - 1]) && dp[i - 1][0];
}
// Process all characters of s1 and s2
for (let i = 1; i <= m; ++i) {
for (let j = 1; j <= n; ++j) {
let k = i + j;
dp[i][j]
= (s1[i - 1] === s3[k - 1] && dp[i - 1][j])
|| (s2[j - 1] === s3[k - 1]
&& dp[i][j - 1]);
}
}
return dp[m][n];
}
// Driver Code
let s1 = "AAB";
let s2 = "AAC";
let s3 = "AAAABC";
console.log(isInterleave(s1, s2, s3) ? "true" : "false");
[Expected Approach] Space-Optimized DP - O(n * m) Time and O(m) Space
The idea is to optimize DP space by using two 1D arrays instead of a 2D table.
We check if s3 can be formed by interleaving s1 and s2 while maintaining relative order. prev stores results of the previous row, while cur stores the current row values.
We fill the first row for cases where s1 is empty, then iterate through both strings, updating cur[j] based on matches with s3. After processing a row, prev is updated with cur, ensuring space efficiency.
Steps to implement the above idea:
- Check if the total length matches, return false if not.
- Initialize two arrays prev and cur to store previous and current results.
- Set the base case where an empty prefix is valid.
- Fill the first row based on matches with s2.
- Iterate through both s1 and s2, updating cur based on matches.
- Return cur[m], indicating interleaving validity.
C++
// CPP program to check if a string is
// interleaving of other two strings
#include <bits/stdc++.h>
using namespace std;
bool isInterleave(string &s1, string &s2, string &s3)
{
// return false is length of s3 is
// not equal to sum of lengths of s1 and s2
if (s1.size() + s2.size() != s3.size())
return false;
int n = s1.size(), m = s2.size();
// Create two arrays prev and cur to store
// results of previous and current states
vector<int> prev(m + 1), cur(m + 1);
// set empty strings as true
prev[0] = true;
// Fill the first row (when s1 is empty)
for (int j = 1; j <= m; ++j)
{
prev[j] = (s2[j - 1] == s3[j - 1]) && prev[j - 1];
}
// Process all characters of s1 and s2
for (int i = 1; i <= n; ++i)
{
// fill the first column of current row
cur[0] = (s1[i - 1] == s3[i - 1]) && prev[0];
for (int j = 1; j <= m; ++j)
{
int k = i + j;
cur[j] = (s1[i - 1] == s3[k - 1] && prev[j]) || (s2[j - 1] == s3[k - 1] && cur[j - 1]);
}
// store current row in previous row
prev = cur;
}
return cur[m];
}
int main()
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
cout << (isInterleave(s1, s2, s3) ? "true" : "false");
return 0;
}
Java
// Java program to check if a string is
// interleaving of other two strings
import java.util.*;
class GfG {
static boolean isInterleave(String s1, String s2,
String s3)
{
// return false if length of s3 is
// not equal to sum of lengths of s1 and s2
if (s1.length() + s2.length() != s3.length())
return false;
int n = s1.length(), m = s2.length();
// Create two arrays prev and cur to store
// results of previous and current states
int[] prev = new int[m + 1];
int[] cur = new int[m + 1];
// set empty strings as true
prev[0] = 1;
// Fill the first row (when s1 is empty)
for (int j = 1; j <= m; ++j) {
prev[j] = (s2.charAt(j - 1) == s3.charAt(j - 1))
&& (prev[j - 1] == 1)
? 1
: 0;
}
// Process all characters of s1 and s2
for (int i = 1; i <= n; ++i) {
// fill the first column of current row
cur[0] = (s1.charAt(i - 1) == s3.charAt(i - 1))
&& (prev[0] == 1)
? 1
: 0;
for (int j = 1; j <= m; ++j) {
int k = i + j;
cur[j]
= ((s1.charAt(i - 1) == s3.charAt(k - 1)
&& prev[j] == 1)
|| (s2.charAt(j - 1)
== s3.charAt(k - 1)
&& cur[j - 1] == 1))
? 1
: 0;
}
// store current row in previous row
prev = Arrays.copyOf(cur, m + 1);
}
return cur[m] == 1;
}
public static void main(String[] args)
{
String s1 = "AAB";
String s2 = "AAC";
String s3 = "AAAABC";
System.out.println(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
Python
# Python program to check if a string is
# interleaving of other two strings
def isInterleave(s1, s2, s3):
# return false if length of s3 is
# not equal to sum of lengths of s1 and s2
if len(s1) + len(s2) != len(s3):
return False
n, m = len(s1), len(s2)
# Create two arrays prev and cur to store
# results of previous and current states
prev = [0] * (m + 1)
cur = [0] * (m + 1)
# set empty strings as true
prev[0] = 1
# Fill the first row (when s1 is empty)
for j in range(1, m + 1):
prev[j] = int(s2[j - 1] == s3[j - 1] and prev[j - 1])
# Process all characters of s1 and s2
for i in range(1, n + 1):
# fill the first column of current row
cur[0] = int(s1[i - 1] == s3[i - 1] and prev[0])
for j in range(1, m + 1):
k = i + j
cur[j] = int((s1[i - 1] == s3[k - 1] and prev[j]) or
(s2[j - 1] == s3[k - 1] and cur[j - 1]))
# store current row in previous row
prev = cur[:]
return cur[m] == 1
if __name__ == "__main__":
s1 = "AAB"
s2 = "AAC"
s3 = "AAAABC"
print("true" if isInterleave(s1, s2, s3) else "false")
C#
// C# program to check if a string is
// interleaving of other two strings
using System;
class GfG {
static bool isInterleave(string s1, string s2,
string s3)
{
// return false if length of s3 is
// not equal to sum of lengths of s1 and s2
if (s1.Length + s2.Length != s3.Length)
return false;
int n = s1.Length, m = s2.Length;
// Create two arrays prev and cur to store
// results of previous and current states
int[] prev = new int[m + 1];
int[] cur = new int[m + 1];
// set empty strings as true
prev[0] = 1;
// Fill the first row (when s1 is empty)
for (int j = 1; j <= m; ++j) {
prev[j] = (s2[j - 1] == s3[j - 1]
&& prev[j - 1] == 1)
? 1
: 0;
}
// Process all characters of s1 and s2
for (int i = 1; i <= n; ++i) {
// fill the first column of current row
cur[0]
= (s1[i - 1] == s3[i - 1] && prev[0] == 1)
? 1
: 0;
for (int j = 1; j <= m; ++j) {
int k = i + j;
cur[j] = ((s1[i - 1] == s3[k - 1]
&& prev[j] == 1)
|| (s2[j - 1] == s3[k - 1]
&& cur[j - 1] == 1))
? 1
: 0;
}
// store current row in previous row
Array.Copy(cur, prev, m + 1);
}
return cur[m] == 1;
}
static void Main()
{
string s1 = "AAB";
string s2 = "AAC";
string s3 = "AAAABC";
Console.WriteLine(
isInterleave(s1, s2, s3) ? "true" : "false");
}
}
JavaScript
// JavaScript program to check if a string is
// interleaving of other two strings
function isInterleave(s1, s2, s3)
{
// return false if length of s3 is
// not equal to sum of lengths of s1 and s2
if (s1.length + s2.length !== s3.length)
return false;
const n = s1.length, m = s2.length;
// Create two arrays prev and cur to store
// results of previous and current states
const prev = Array(m + 1).fill(0);
const cur = Array(m + 1).fill(0);
// set empty strings as true
prev[0] = 1;
// Fill the first row (when s1 is empty)
for (let j = 1; j <= m; ++j) {
prev[j] = (s2[j - 1] === s3[j - 1] && prev[j - 1])
? 1
: 0;
}
// Process all characters of s1 and s2
for (let i = 1; i <= n; ++i) {
// fill the first column of current row
cur[0]
= (s1[i - 1] === s3[i - 1] && prev[0]) ? 1 : 0;
for (let j = 1; j <= m; ++j) {
const k = i + j;
cur[j] = ((s1[i - 1] === s3[k - 1] && prev[j])
|| (s2[j - 1] === s3[k - 1]
&& cur[j - 1]))
? 1
: 0;
}
// store current row in previous row
prev.splice(0, m + 1, ...cur);
}
return !!cur[m];
}
// Driver Code
const s1 = "AAB";
const s2 = "AAC";
const s3 = "AAAABC";
console.log(isInterleave(s1, s2, s3) ? "true" : "false");
Check whether a given string is an interleaving of two other given strings
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem