Longest common subarray in the given two arrays
Given two arrays A[] and B[] of N and M integers respectively, the task is to find the maximum length of an equal subarray or the longest common subarray between the two given array.
Examples:
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[].
Naive Approach: The idea is to generate all the subarrays of the two given array A[] and B[] and find the longest matching subarray. This solution is exponential in terms of time complexity.
C++
#include <iostream>
#include <vector>
using namespace std;
int LCS( int i, int j, const vector< int >& A, const vector< int >& B, int count) {
if (i == A.size() || j == B.size())
return count;
if (A[i] == B[j])
count = LCS(i + 1, j + 1, A, B, count + 1);
count = max(count, max(LCS(i + 1, j, A, B, 0), LCS(i, j + 1, A, B, 0)));
return count;
}
int main() {
vector< int > A = {1, 2, 3, 2, 1};
vector< int > B = {3, 2, 1, 4, 7};
int maxLength = LCS(0, 0, A, B, 0);
cout << "Max length of common subarray: " << maxLength << endl;
return 0;
}
|
Java
import java.util.Arrays;
import java.util.Vector;
public class Main {
static int LCS( int i, int j, Vector<Integer> A,
Vector<Integer> B, int count) {
if (i == A.size() || j == B.size())
return count;
if (A.get(i).equals(B.get(j)))
count = LCS(i + 1 , j + 1 , A, B, count + 1 );
count = Math.max(count, Math.max(LCS(i + 1 , j, A, B, 0 ),
LCS(i, j + 1 , A, B, 0 )));
return count;
}
public static void main(String[] args) {
Vector<Integer> A = new Vector<>(Arrays.asList( 1 , 2 , 3 , 2 , 1 ));
Vector<Integer> B = new Vector<>(Arrays.asList( 3 , 2 , 1 , 4 , 7 ));
int maxLength = LCS( 0 , 0 , A, B, 0 );
System.out.println( "Max length of common subarray: " + maxLength);
}
}
|
Python3
def LCS(i, j, A, B, count):
if i = = len (A) or j = = len (B):
return count
if A[i] = = B[j]:
count = LCS(i + 1 , j + 1 , A, B, count + 1 )
return max (count, max (LCS(i + 1 , j, A, B, 0 ), LCS(i, j + 1 , A, B, 0 )))
A = [ 1 , 2 , 3 , 2 , 1 ]
B = [ 3 , 2 , 1 , 4 , 7 ]
maxLength = LCS( 0 , 0 , A, B, 0 )
print ( "Max length of common subarray:" , maxLength)
|
C#
using System;
class GFG {
static int LCS( int i, int j, int [] A, int [] B,
int count)
{
if (i == A.Length || j == B.Length)
return count;
if (A[i] == B[j])
count = LCS(i + 1, j + 1, A, B, count + 1);
count = Math.Max(count,
Math.Max(LCS(i + 1, j, A, B, 0),
LCS(i, j + 1, A, B, 0)));
return count;
}
static void Main()
{
int [] A = { 1, 2, 3, 2, 1 };
int [] B = { 3, 2, 1, 4, 7 };
int maxLength = LCS(0, 0, A, B, 0);
Console.WriteLine( "Max length of common subarray: "
+ maxLength);
}
}
|
Javascript
function LCS(i, j, A, B, count) {
if (i === A.length || j === B.length) {
return count;
}
if (A[i] === B[j]) {
count = LCS(i + 1, j + 1, A, B, count + 1);
}
count = Math.max(count, Math.max(LCS(i + 1, j, A, B, 0), LCS(i, j + 1, A, B, 0)));
return count;
}
const A = [1, 2, 3, 2, 1];
const B = [3, 2, 1, 4, 7];
const maxLength = LCS(0, 0, A, B, 0);
console.log( "Max length of common subarray: " + maxLength);
|
Output
Max length of common subarray: 3
Time Complexity: O(2N+M), where N is the length of the array A[] and M is the length of the array B[].
Efficient Approach:
The efficient approach is to use Dynamic Programming(DP). This problem is the variation of the Longest Common Subsequence(LCS).
Let the input sequences are A[0..n-1] and B[0..m-1] of lengths m & n respectively. Following is the recursive implementation of the equal subarrays:
- Since common subarray of A[] and B[] must start at some index i and j such that A[i] is equals to B[j]. Let dp[i][j] be the longest common subarray of A[i…] and B[j…].
- Therefore, for any index i and j, if A[i] is equals to B[j], then dp[i][j] = dp[i+1][j+1] + 1.
- The maximum of all the elements in the array dp[][] will give the maximum length of equal subarrays.
For Example:
If the given array A[] = {1, 2, 8, 2, 1} and B[] = {8, 2, 1, 4, 7}.
If the characters match at index i and j for the array A[] and B[] respectively, then dp[i][j] will be updated as 1 + dp[i+1][j+1].
Below is the updated dp[][] table for the given array A[] and B[].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int FindMaxLength( int A[], int B[], int n, int m)
{
int dp[n + 1][m + 1];
for ( int i = 0; i <= n; i++)
for ( int j = 0; j <= m; j++)
dp[i][j] = 0;
for ( int i = n - 1; i >= 0; i--) {
for ( int j = m - 1; j >= 0; j--) {
if (A[i] == B[j])
dp[i][j] = dp[i + 1][j + 1] + 1;
}
}
int maxm = 0;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
maxm = max(maxm, dp[i][j]);
}
}
return maxm;
}
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]);
cout << (FindMaxLength(A, B, n, m));
}
|
Java
class GFG
{
static int FindMaxLength( int A[], int B[], int n, int m)
{
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 ;
for ( int i = n - 1 ; i >= 0 ; i--)
{
for ( int j = m - 1 ; j >= 0 ; j--)
{
if (A[i] == B[j])
dp[i][j] = dp[i + 1 ][j + 1 ] + 1 ;
}
}
int maxm = 0 ;
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < m; j++)
{
maxm = Math.max(maxm, dp[i][j]);
}
}
return maxm;
}
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;
System.out.print(FindMaxLength(A, B, n, m));
}
}
|
Python3
def FindMaxLength(A, B):
n = len (A)
m = len (B)
dp = [[ 0 for i in range (n + 1 )] for i in range (m + 1 )]
for i in range (n - 1 , - 1 , - 1 ):
for j in range (m - 1 , - 1 , - 1 ):
if A[i] = = B[j]:
dp[i][j] = dp[i + 1 ][j + 1 ] + 1
maxm = 0
for i in dp:
for j in i:
maxm = max (maxm, j)
return maxm
if __name__ = = '__main__' :
A = [ 1 , 2 , 8 , 2 , 1 ]
B = [ 8 , 2 , 1 , 4 , 7 ]
print (FindMaxLength(A, B))
|
C#
using System;
class GFG
{
static int FindMaxLength( int [] A, int [] B, int n, int m)
{
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;
for ( int i = n - 1; i >= 0; i--)
{
for ( int j = m - 1; j >= 0; j--)
{
if (A[i] == B[j])
dp[i, j] = dp[i + 1, j + 1] + 1;
}
}
int maxm = 0;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
maxm = Math.Max(maxm, dp[i, j]);
}
}
return maxm;
}
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;
Console.Write(FindMaxLength(A, B, n, m));
}
}
|
Javascript
<script>
function FindMaxLength(A,B,n,m)
{
let dp = new Array(n + 1);
for (let i = 0; i <= n; i++)
{
dp[i]= new Array(m+1);
for (let j = 0; j <= m; j++)
dp[i][j] = 0;
}
for (let i = n - 1; i >= 0; i--)
{
for (let j = m - 1; j >= 0; j--)
{
if (A[i] == B[j])
dp[j][i] = dp[j + 1][i + 1] + 1;
}
}
let maxm = 0;
for (let i = 0; i < n; i++)
{
for (let j = 0; j < m; j++)
{
maxm = Math.max(maxm, dp[i][j]);
}
}
return maxm;
}
let A=[1, 2, 8, 2, 1 ];
let B=[8, 2, 1, 4, 7];
let n = A.length;
let m = B.length;
document.write(FindMaxLength(A, B, n, m));
</script>
|
Time Complexity: O(N*M), where N is the length of array A[] and M is the length of array B[].
Auxiliary Space: O(N*M)
Efficient approach: space optimization
In previous approach the dp[i][j] is depend upon the current and previous row of 2D matrix. So to optimize the space complexity we use only single vector dp for current row and a variable prev to get the previous computation.
Implementation Steps :
- Create a vector DP of size M+1 , that stores the computation of subproblems and initialize it with 0.
- Initialize a variable maxm with 0 used to store the maximum length.
- Now iterative over subproblems and update the DP vector in bottom up approach.
- Initialize variable prev and temp. prev is used to get the previous row value of Dp and temp is used to get the value of prev in another iteration.
- While iterating update the maxm with respect to the value stored in DP.
- At last return the maxm.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int FindMaxLength( int A[], int B[], int n, int m)
{
vector< int > dp(m + 1, 0);
int maxm = 0;
for ( int i = n - 1; i >= 0; i--) {
int prev = 0;
for ( int j = m - 1; j >= 0; j--) {
int temp = dp[j];
if (A[i] == B[j]) {
dp[j] = prev + 1;
maxm = max(maxm, dp[j]);
}
else {
dp[j] = 0;
}
prev = temp;
}
}
return maxm;
}
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]);
cout << (FindMaxLength(A, B, n, m));
}
|
Java
import java.util.Arrays;
public class Main {
static int findMaxLength( int [] A, int [] B, int n, int m) {
int [] dp = new int [m + 1 ];
int maxm = 0 ;
for ( int i = n - 1 ; i >= 0 ; i--) {
int prev = 0 ;
for ( int j = m - 1 ; j >= 0 ; j--) {
int temp = dp[j];
if (A[i] == B[j]) {
dp[j] = prev + 1 ;
maxm = Math.max(maxm, dp[j]);
} else {
dp[j] = 0 ;
}
prev = temp;
}
}
return maxm;
}
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;
System.out.println(findMaxLength(A, B, n, m));
}
}
|
Python3
def find_max_length(A, B, n, m):
dp = [ 0 ] * (m + 1 )
maxm = 0
for i in range (n - 1 , - 1 , - 1 ):
prev = 0
for j in range (m - 1 , - 1 , - 1 ):
temp = dp[j]
if A[i] = = B[j]:
dp[j] = prev + 1
maxm = max (maxm, dp[j])
else :
dp[j] = 0
prev = temp
return maxm
if __name__ = = '__main__' :
A = [ 1 , 2 , 8 , 2 , 1 ]
B = [ 8 , 2 , 1 , 4 , 7 ]
n = len (A)
m = len (B)
print (find_max_length(A, B, n, m))
|
C#
using System;
class Program
{
static int FindMaxLength( int [] A, int [] B, int n, int m)
{
int [] dp = new int [m + 1];
int maxm = 0;
for ( int i = n - 1; i >= 0; i--)
{
int prev = 0;
for ( int j = m - 1; j >= 0; j--)
{
int temp = dp[j];
if (A[i] == B[j])
{
dp[j] = prev + 1;
maxm = Math.Max(maxm, dp[j]);
}
else
{
dp[j] = 0;
}
prev = temp;
}
}
return maxm;
}
static void Main()
{
int [] A = { 1, 2, 8, 2, 1 };
int [] B = { 8, 2, 1, 4, 7 };
int n = A.Length;
int m = B.Length;
Console.WriteLine(FindMaxLength(A, B, n, m));
}
}
|
Javascript
function FindMaxLength(A, B, n, m) {
let dp = new Array(m + 1).fill(0);
let maxm = 0;
for (let i = n - 1; i >= 0; i--) {
let prev = 0;
for (let j = m - 1; j >= 0; j--) {
let temp = dp[j];
if (A[i] == B[j]) {
dp[j] = prev + 1;
maxm = Math.max(maxm, dp[j]);
} else {
dp[j] = 0;
}
prev = temp;
}
}
return maxm;
}
let A = [1, 2, 8, 2, 1];
let B = [8, 2, 1, 4, 7];
let n = A.length;
let m = B.length;
console.log(FindMaxLength(A, B, n, m));
|
Time Complexity: O(N*M)
Auxiliary Space: O(M) , only use one vector dp of size M
Last Updated :
09 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...