给定两个分别由N 和 M 个整数组成的数组A[] 和 B[] ,任务是找到相等子数组的最大长度或两个给定数组之间的最长公共子数组。
例子:
Input: A[] = {1, 2, 8, 2, 1}, B[] = {8, 2, 1, 4, 7}
Output: 3
Explanation:
The subarray that is common to both arrays are {8, 2, 1} and the length of the subarray is 3.
Input: A[] = {1, 2, 3, 2, 1}, B[] = {8, 7, 6, 4, 7}
Output: 0
Explanation:
There is no such subarrays which are equal in the array A[] and B[].
朴素的方法:想法是生成两个给定数组A[]和B[] 的所有子数组,并找到最长的匹配子数组。该解决方案在时间复杂度方面呈指数级增长。
时间复杂度: O(2 N+M ),其中 N 是数组A[]的长度,M 是数组B[]的长度。
有效的方法:
有效的方法是使用动态规划(DP)。这个问题是最长公共子序列(LCS)的变异。
让输入序列分别是长度为m & n 的A[0..n-1]和B[0..m-1] 。以下是相等子数组的递归实现:
- 由于A[]和B[] 的公共子数组必须从某个索引i和j 开始,使得A[i]等于B[j] 。令dp[i][j]是A[i…] 和 B[j…]的最长公共子数组。
- 因此,对于任何索引 i 和 j,如果 A[i] 等于 B[j],则dp[i][j] = dp[i+1][j+1] + 1 。
- 数组dp[][]中所有元素的最大值将给出相等子数组的最大长度。
例如:
如果给定的数组A[] = {1, 2, 8, 2, 1} 和B[] = {8, 2, 1, 4, 7}。如果字符在数组A[]和B[] 的索引i和j处匹配,则dp[i][j]将更新为1 + dp[i+1][j+1] 。
下面是给定数组A[]和B[]的更新后的dp[][]表。
下面是上述方法的实现:
C++
// C++ program to DP approach
// to above solution
#include
using namespace std;
// Function to find the maximum
// length of equal subarray
int FindMaxLength(int A[], int B[], int n, int m)
{
// Auxiliary dp[][] array
int dp[n + 1][m + 1];
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
dp[i][j] = 0;
// Updating the dp[][] table
// in Bottom Up approach
for (int i = n - 1; i >= 0; i--)
{
for (int j = m - 1; j >= 0; j--)
{
// If A[i] is equal to B[i]
// then dp[j][i] = dp[j + 1][i + 1] + 1
if (A[i] == B[j])
dp[j][i] = dp[j + 1][i + 1] + 1;
}
}
int maxm = 0;
// Find maximum of all the values
// in dp[][] array to get the
// maximum length
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// Update the length
maxm = max(maxm, dp[i][j]);
}
}
// Return the maximum length
return maxm;
}
// Driver Code
int main()
{
int A[] = { 1, 2, 8, 2, 1 };
int B[] = { 8, 2, 1, 4, 7 };
int n = sizeof(A) / sizeof(A[0]);
int m = sizeof(B) / sizeof(B[0]);
// Function call to find
// maximum length of subarray
cout << (FindMaxLength(A, B, n, m));
}
// This code is contributed by chitranayal
Java
// Java program to DP approach
// to above solution
class GFG
{
// Function to find the maximum
// length of equal subarray
static int FindMaxLength(int A[], int B[], int n, int m)
{
// Auxiliary dp[][] array
int[][] dp = new int[n + 1][m + 1];
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
dp[i][j] = 0;
// Updating the dp[][] table
// in Bottom Up approach
for (int i = n - 1; i >= 0; i--)
{
for (int j = m - 1; j >= 0; j--)
{
// If A[i] is equal to B[i]
// then dp[j][i] = dp[j + 1][i + 1] + 1
if (A[i] == B[j])
dp[j][i] = dp[j + 1][i + 1] + 1;
}
}
int maxm = 0;
// Find maximum of all the values
// in dp[][] array to get the
// maximum length
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// Update the length
maxm = Math.max(maxm, dp[i][j]);
}
}
// Return the maximum length
return maxm;
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 1, 2, 8, 2, 1 };
int B[] = { 8, 2, 1, 4, 7 };
int n = A.length;
int m = B.length;
// Function call to find
// maximum length of subarray
System.out.print(FindMaxLength(A, B, n, m));
}
}
// This code is contributed by PrinciRaj1992
Python
# Python program to DP approach
# to above solution
# Function to find the maximum
# length of equal subarray
def FindMaxLength(A, B):
n = len(A)
m = len(B)
# Auxiliary dp[][] array
dp = [[0 for i in range(n + 1)] for i in range(m + 1)]
# Updating the dp[][] table
# in Bottom Up approach
for i in range(n - 1, -1, -1):
for j in range(m - 1, -1, -1):
# If A[i] is equal to B[i]
# then dp[j][i] = dp[j + 1][i + 1] + 1
if A[i] == B[j]:
dp[j][i] = dp[j + 1][i + 1] + 1
maxm = 0
# Find maximum of all the values
# in dp[][] array to get the
# maximum length
for i in dp:
for j in i:
# Update the length
maxm = max(maxm, j)
# Return the maximum length
return maxm
# Driver Code
if __name__ == '__main__':
A = [1, 2, 8, 2, 1]
B = [8, 2, 1, 4, 7]
# Function call to find
# maximum length of subarray
print(FindMaxLength(A, B))
C#
// C# program to DP approach
// to above solution
using System;
class GFG
{
// Function to find the maximum
// length of equal subarray
static int FindMaxLength(int[] A, int[] B, int n, int m)
{
// Auxiliary [,]dp array
int[, ] dp = new int[n + 1, m + 1];
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
dp[i, j] = 0;
// Updating the [,]dp table
// in Bottom Up approach
for (int i = n - 1; i >= 0; i--)
{
for (int j = m - 1; j >= 0; j--)
{
// If A[i] is equal to B[i]
// then dp[j, i] = dp[j + 1, i + 1] + 1
if (A[i] == B[j])
dp[j, i] = dp[j + 1, i + 1] + 1;
}
}
int maxm = 0;
// Find maximum of all the values
// in [,]dp array to get the
// maximum length
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// Update the length
maxm = Math.Max(maxm, dp[i, j]);
}
}
// Return the maximum length
return maxm;
}
// Driver Code
public static void Main(String[] args)
{
int[] A = { 1, 2, 8, 2, 1 };
int[] B = { 8, 2, 1, 4, 7 };
int n = A.Length;
int m = B.Length;
// Function call to find
// maximum length of subarray
Console.Write(FindMaxLength(A, B, n, m));
}
}
// This code is contributed by PrinciRaj1992
Javascript
3
时间复杂度: O(N*M),其中 N 是数组 A[] 的长度,M 是数组 B[] 的长度。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。