给出三个字符串A,B和C.编写一个函数,检查是否C是A的交织和B C被说成是交织A和B,如果其含有A和B以及在个体中的所有字符的顺序的所有字符字符串被保留。
例子:
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 Z
Input: 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
简单的解决方案:递归。
方法:这里讨论一个简单的解决方案:检查给定的字符串是否与其他两个给定的字符串交织。
如果字符串A和B具有某些共同的字符,则简单的解决办法无效。例如,假设给定的字符串为A,其他字符串为B和C。假设A =“ XXY”,字符串B =“ XXZ”,字符串C =“ XXZXXXY”。创建一个采用参数A,B和C的递归函数。要处理所有情况,需要考虑两种可能性。
- 如果C的第一个字符的第一个字符相匹配,我们在A和C向前移动一个字符和递归查询。
- 如果C的第一个字符B的第一个字符相匹配,我们在B和C向前移动一个字符和递归查询。
如果以上任何函数返回true或A,B和C为空,则返回true,否则返回false。
感谢Frederic提出了这种方法。
C
// 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));
}
C++
// A Dynamic Programming based program
// to check whether a string C is
// an interleaving of two other
// strings A and B.
#include
#include
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;
}
Java
// A Dynamic Programming based program
// to check whether a string C is
// an interleaving of two other
// strings A and B.
import java.io.*;
import java.util.*;
import java.lang.*;
class GFG{
// The main function that returns
// true if C is an interleaving of A
// and B, otherwise false.
static boolean isInterleaved(String A, String B,
String C)
{
// Find lengths of the two strings
int M = A.length(), N = B.length();
// Let us create a 2D table to store
// solutions of subproblems. C[i][j]
// will br true if C[0..i+j-1] is an
// interleaving of A[0..i-1] and B[0..j-1].
boolean IL[][] = new boolean[M + 1][N + 1];
// IL is default initialised by false
// C can be an interleaving of A and B
// only if the sum of lengths of A and B
// is equal to length of C
if ((M + N) != C.length())
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 strings as interleaving
if (i == 0 && j == 0)
IL[i][j] = true;
// A is empty
else if (i == 0)
{
if (B.charAt(j - 1) ==
C.charAt(j - 1))
IL[i][j] = IL[i][j - 1];
}
// B is empty
else if (j == 0)
{
if (A.charAt(i - 1) ==
C.charAt(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 if B
else if (A.charAt(i - 1) ==
C.charAt(i + j - 1) &&
B.charAt(j - 1) !=
C.charAt(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 if A
else if (A.charAt(i - 1) !=
C.charAt(i + j - 1) &&
B.charAt(j - 1) ==
C.charAt(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.charAt(i - 1) ==
C.charAt(i + j - 1) &&
B.charAt(j - 1) ==
C.charAt(i + j - 1))
IL[i][j] = (IL[i - 1][j] ||
IL[i][j - 1]);
}
}
return IL[M][N];
}
// Function to run test cases
static void test(String A, String B, String C)
{
if (isInterleaved(A, B, C))
System.out.println(C + " is interleaved of " +
A + " and " + B);
else
System.out.println(C + " is not interleaved of " +
A + " and " + B);
}
// Driver code
public static void main(String[] args)
{
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 th_aditi
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
C#
// A Dynamic Programming based program
// to check whether a string C is
// an interleaving of two other
// strings A and B.
using System;
class GFG
{
// The main function that returns
// true if C is an interleaving of A
// and B, otherwise false.
static bool isInterleaved(string A, string B,
string C)
{
// Find lengths of the two strings
int M = A.Length, N = B.Length;
// Let us create a 2D table to store
// solutions of subproblems. C[i][j]
// will br true if C[0..i+j-1] is an
// interleaving of A[0..i-1] and B[0..j-1].
bool[ , ] IL = new bool[M + 1, N + 1];
// IL is default initialised by false
// C can be an interleaving of A and B
// only if the sum of lengths of A and B
// is equal to length of C
if ((M + N) != C.Length)
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 strings 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 if 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 if 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];
}
// Function to run test cases
static void test(string A, string B, string C)
{
if (isInterleaved(A, B, C))
Console.WriteLine(C + " is interleaved of " +
A + " and " + B);
else
Console.WriteLine(C + " is not interleaved of " +
A + " and " + B);
}
// Driver code
static void 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 divyeshrabadiya07
复杂度分析:
- 时间复杂度: O(n),其中n是给定字符串的长度。
我们只需要迭代整个字符串一次,因此在O(n)中是可能的。 - 空间复杂度: O(1)。
空间复杂度是恒定的。
高效的解决方案:动态编程。
方法:以上递归解决方案当然有许多重叠的子问题。例如,如果我们考虑A =“ XXX”,B =“ XXX”和C =“ XXXXXX”并绘制一个递归树,则将存在许多重叠的子问题。因此,与其他任何典型的动态编程问题一样,我们可以通过创建表并以自底向上的方式存储子问题的结果来解决该问题。可以通过添加哈希图来修改上述解决方案的自上而下的方法。
算法:
- 创建大小为M * N的DP数组(矩阵),其中m是第一个字符串的大小,n是第二个字符串的大小。将矩阵初始化为false。
- 如果较小的字符串的大小之和不等于较大的字符串的大小,则返回false并破坏数组,因为它们无法交织以形成较大的字符串。
- 运行嵌套循环,外部循环从0到m,内部循环从0到n。循环计数器是i和j。
- 如果i和j的值都为零,则将dp [i] [j]标记为true。如果i的值为零且j为非零且B的j-1字符等于C的j-1字符,则将dp [i] [j]分配为dp [i] [j-1]如果j为0,则匹配C和A的第i-1个字符;如果匹配,则将dp [i] [j]分配为dp [i-1] [j]。
- 取三个字符X,Y,Z如(I-1)A的个字符和(j-1)B的个字符和(I + J – 1)C的个字符
- 如果x与z匹配且y与z不匹配,则类似地将dp [i] [j]分配为dp [i-1] [j],如果x不等于z且y等于z,则分配dp [i ] [j]作为dp [i] [j-1]
- 如果x等于y并且y等于z,则将dp [i] [j]分配为dp [i] [j-1]和dp [i-1] [j]的按位或。
- dp [m] [n]的返回值。
感谢Abhinav Ramana提出了这种实现方法。
C++
// A Dynamic Programming based program
// to check whether a string C is
// an interleaving of two other
// strings A and B.
#include
#include
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;
}
Java
// A Dynamic Programming based program
// to check whether a string C is
// an interleaving of two other
// strings A and B.
import java.io.*;
import java.util.*;
import java.lang.*;
class GFG{
// The main function that returns
// true if C is an interleaving of A
// and B, otherwise false.
static boolean isInterleaved(String A, String B,
String C)
{
// Find lengths of the two strings
int M = A.length(), N = B.length();
// Let us create a 2D table to store
// solutions of subproblems. C[i][j]
// will br true if C[0..i+j-1] is an
// interleaving of A[0..i-1] and B[0..j-1].
boolean IL[][] = new boolean[M + 1][N + 1];
// IL is default initialised by false
// C can be an interleaving of A and B
// only if the sum of lengths of A and B
// is equal to length of C
if ((M + N) != C.length())
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 strings as interleaving
if (i == 0 && j == 0)
IL[i][j] = true;
// A is empty
else if (i == 0)
{
if (B.charAt(j - 1) ==
C.charAt(j - 1))
IL[i][j] = IL[i][j - 1];
}
// B is empty
else if (j == 0)
{
if (A.charAt(i - 1) ==
C.charAt(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 if B
else if (A.charAt(i - 1) ==
C.charAt(i + j - 1) &&
B.charAt(j - 1) !=
C.charAt(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 if A
else if (A.charAt(i - 1) !=
C.charAt(i + j - 1) &&
B.charAt(j - 1) ==
C.charAt(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.charAt(i - 1) ==
C.charAt(i + j - 1) &&
B.charAt(j - 1) ==
C.charAt(i + j - 1))
IL[i][j] = (IL[i - 1][j] ||
IL[i][j - 1]);
}
}
return IL[M][N];
}
// Function to run test cases
static void test(String A, String B, String C)
{
if (isInterleaved(A, B, C))
System.out.println(C + " is interleaved of " +
A + " and " + B);
else
System.out.println(C + " is not interleaved of " +
A + " and " + B);
}
// Driver code
public static void main(String[] args)
{
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 th_aditi
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
C#
// A Dynamic Programming based program
// to check whether a string C is
// an interleaving of two other
// strings A and B.
using System;
class GFG
{
// The main function that returns
// true if C is an interleaving of A
// and B, otherwise false.
static bool isInterleaved(string A, string B,
string C)
{
// Find lengths of the two strings
int M = A.Length, N = B.Length;
// Let us create a 2D table to store
// solutions of subproblems. C[i][j]
// will br true if C[0..i+j-1] is an
// interleaving of A[0..i-1] and B[0..j-1].
bool[ , ] IL = new bool[M + 1, N + 1];
// IL is default initialised by false
// C can be an interleaving of A and B
// only if the sum of lengths of A and B
// is equal to length of C
if ((M + N) != C.Length)
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 strings 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 if 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 if 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];
}
// Function to run test cases
static void test(string A, string B, string C)
{
if (isInterleaved(A, B, C))
Console.WriteLine(C + " is interleaved of " +
A + " and " + B);
else
Console.WriteLine(C + " is not interleaved of " +
A + " and " + B);
}
// Driver code
static void 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 divyeshrabadiya07
输出:
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
有关更多测试案例,请参见此内容。
复杂度分析:
- 时间复杂度: O(M * N)。
由于需要遍历DP数组,因此时间复杂度为O(M * N)。 - 空间复杂度: O(M * N)。
这是存储DP阵列所需的空间。