Given an arr[], the task is to find the maximum length of the sub-array such that the LCM of the sub-array is equal to the product of numbers in the sub-array. If no valid sub-array exists, then print -1.
Note: The length of the sub-array must be ? 2.
Examples:
Input: arr[] = { 6, 10, 21}
Output: 2
The sub-array { 10, 21 } satisfies the condition.Input: arr[] = { 2, 2, 4}
Output: -1
No sub-array satisfies the condition. Hence, the output is -1.
Naive Approach: Run nested loops to check the condition for every possible sub-array of length ? 2. If the sub-array satisfies the condition, then update ans = max(ans, length(sub-array)). Print the ans in the end.
Below is the implementation of the above approach:
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std;
#define ll long long // Function to calculate gcd(a, b) int gcd( int a, int b)
{ if (b == 0)
return a;
return gcd(b, a % b);
} // Function to return max length of subarray // that satisfies the condition int maxLengthSubArray( const int * arr, int n)
{ int maxLen = -1;
for ( int i = 0; i < n - 1; i++) {
for ( int j = i + 1; j < n; j++) {
ll lcm = 1LL * arr[i];
ll product = 1LL * arr[i];
// Update LCM and product of the
// sub-array
for ( int k = i + 1; k <= j; k++) {
lcm = (((arr[k] * lcm)) /
(gcd(arr[k], lcm)));
product = product * arr[k];
}
// If the current sub-array satisfies
// the condition
if (lcm == product) {
// Choose the maximum
maxLen = max(maxLen, j - i + 1);
}
}
}
return maxLen;
} // Driver code int main()
{ int arr[] = { 6, 10, 21 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxLengthSubArray(arr, n);
return 0;
} |
// Java implementation of the above approach import java.util.*;
class GFG
{ // Function to calculate gcd(a, b) static int gcd( int a, int b)
{ if (b == 0 )
return a;
return gcd(b, a % b);
} // Function to return max length of subarray // that satisfies the condition static int maxLengthSubArray( int arr[], int n)
{ int maxLen = - 1 ;
for ( int i = 0 ; i < n - 1 ; i++)
{
for ( int j = i + 1 ; j < n; j++)
{
int lcm = 1 * arr[i];
int product = 1 * arr[i];
// Update LCM and product of the
// sub-array
for ( int k = i + 1 ; k <= j; k++)
{
lcm = (((arr[k] * lcm)) /
(gcd(arr[k], lcm)));
product = product * arr[k];
}
// If the current sub-array satisfies
// the condition
if (lcm == product)
{
// Choose the maximum
maxLen = Math.max(maxLen, j - i + 1 );
}
}
}
return maxLen;
} // Driver code public static void main(String args[])
{ int arr[] = { 6 , 10 , 21 };
int n = arr.length;
System.out.println(maxLengthSubArray(arr, n));
} } // This code is contributed by // Shashank_Sharma |
# Python3 implementation of the # above approach # Function to calculate gcd(a, b) def gcd(a, b):
if (b = = 0 ):
return a
return gcd(b, a % b)
# Function to return max length of # subarray that satisfies the condition def maxLengthSubArray(arr, n):
maxLen = - 1
for i in range (n - 1 ):
for j in range (n):
lcm = arr[i]
product = arr[i]
# Update LCM and product of the
# sub-array
for k in range (i + 1 , j + 1 ):
lcm = (((arr[k] * lcm)) / /
(gcd(arr[k], lcm)))
product = product * arr[k]
# If the current sub-array satisfies
# the condition
if (lcm = = product):
# Choose the maximum
maxLen = max (maxLen, j - i + 1 )
return maxLen
# Driver code arr = [ 6 , 10 , 21 ]
n = len (arr)
print (maxLengthSubArray(arr, n))
# This code is contributed by # mohit kumar 29 |
// C# implementation of the above approach using System;
class GFG
{ // Function to calculate gcd(a, b) static int gcd( int a, int b)
{ if (b == 0)
return a;
return gcd(b, a % b);
} // Function to return max length of subarray // that satisfies the condition static int maxLengthSubArray( int [] arr, int n)
{ int maxLen = -1;
for ( int i = 0; i < n - 1; i++)
{
for ( int j = i + 1; j < n; j++)
{
int lcm = 1 * arr[i];
int product = 1 * arr[i];
// Update LCM and product of the
// sub-array
for ( int k = i + 1; k <= j; k++)
{
lcm = (((arr[k] * lcm)) /
(gcd(arr[k], lcm)));
product = product * arr[k];
}
// If the current sub-array satisfies
// the condition
if (lcm == product)
{
// Choose the maximum
maxLen = Math.Max(maxLen, j - i + 1);
}
}
}
return maxLen;
} // Driver code public static void Main()
{ int [] arr = { 6, 10, 21 };
int n = arr.Length;
Console.Write(maxLengthSubArray(arr, n));
} } // This code is contributed by ita_c |
<?php // PHP implementation of the above approach // Function to calculate gcd(a, b) function gcd( $a , $b )
{ if ( $b == 0)
return $a ;
return gcd( $b , $a % $b );
} // Function to return max length of subarray // that satisfies the condition function maxLengthSubArray(& $arr , $n )
{ $maxLen = -1;
for ( $i = 0; $i < $n - 1; $i ++)
{
for ( $j = $i + 1; $j < $n ; $j ++)
{
$lcm = $arr [ $i ];
$product = $arr [ $i ];
// Update LCM and product of the
// sub-array
for ( $k = $i + 1; $k <= $j ; $k ++)
{
$lcm = ((( $arr [ $k ] * $lcm )) /
(gcd( $arr [ $k ], $lcm )));
$product = $product * $arr [ $k ];
}
// If the current sub-array satisfies
// the condition
if ( $lcm == $product )
{
// Choose the maximum
$maxLen = max( $maxLen , $j - $i + 1);
}
}
}
return $maxLen ;
} // Driver code $arr = array (6, 10, 21 );
$n = sizeof( $arr );
echo (maxLengthSubArray( $arr , $n ));
// This code is contributed by Shivi_Aggarwal ?> |
<script> // Javascript implementation of the above approach // Function to calculate gcd(a, b) function gcd(a,b)
{ if (b == 0)
return a;
return gcd(b, a % b);
} // Function to return max length of subarray // that satisfies the condition function maxLengthSubArray(arr,n)
{ let maxLen = -1;
for (let i = 0; i < n - 1; i++)
{
for (let j = i + 1; j < n; j++)
{
let lcm = 1 * arr[i];
let product = 1 * arr[i];
// Update LCM and product of the
// sub-array
for (let k = i + 1; k <= j; k++)
{
lcm = (((arr[k] * lcm)) /
(gcd(arr[k], lcm)));
product = product * arr[k];
}
// If the current sub-array satisfies
// the condition
if (lcm == product)
{
// Choose the maximum
maxLen = Math.max(maxLen, j - i + 1);
}
}
}
return maxLen;
} // Driver code let arr=[6, 10, 21 ]; let n = arr.length; document.write(maxLengthSubArray(arr, n)); // This code is contributed by unknown2108 </script> |
2
Efficient Approach: A sub-array will have its LCM equal to its product when no two elements in the sub-array have any common factor.
For example:
arr[] = { 6, 10, 21 }
Prime factorization yields:
arr[] = { 2 * 3, 2 * 5, 3 * 7 }
[6, 10] has 2 as a common factor.
[6, 10, 21] has 2 as a common factor between 6 and 10.
Sub-array [10, 21] has no common factor between any 2 elements. Therefore, answer = 2.
Firstly, prime factorization of numbers is done to deal with factors. To calculate the sub-array in which no 2 elements have a common factor, we use the two-pointer technique.
Two pointers run, both from the right and they represent the current sub-array. We add elements in the sub-array from the right. Now there are two scenarios:
- An element is added in the current sub-array if it has no factor in common with the current elements in the sub-array. If a common factor is found, then starting from the left, elements are subsequently eliminated until no common factor is found with the newly added element.
- If there are no common factors between the newly added element and existing elements, then update ans = max(ans, length of sub-array)
Below is the implementation of the above approach:
// C++ implementation of the above approach #include <bits/stdc++.h> #define pb push_back #define N 100005 #define MAX 1000002 #define mem(a, b) memset(a, b, sizeof(a)) using namespace std;
int prime[MAX];
// Stores array of primes for every element vector< int > v[N];
// Stores the position of a prime in the subarray // in two pointer technique int f[MAX];
// Function to store smallest prime factor of numbers void sieve()
{ prime[0] = prime[1] = 1;
for ( int i = 2; i < MAX; i++) {
if (!prime[i]) {
for ( int j = i * 2; j < MAX; j += i) {
if (!prime[j])
prime[j] = i;
}
}
}
for ( int i = 2; i < MAX; i++) {
// If number is prime,
// then smallest prime factor is the
// number itself
if (!prime[i])
prime[i] = i;
}
} // Function to return maximum length of subarray // with LCM = product int maxLengthSubArray( int * arr, int n)
{ // Initialize f with -1
mem(f, -1);
for ( int i = 0; i < n; ++i) {
// Prime factorization of numbers
// Store primes in a vector for every element
while (arr[i] > 1) {
int p = prime[arr[i]];
arr[i] /= p;
v[i].pb(p);
}
}
// Two pointers l and r
// denoting left and right of subarray
int l = 0, r = 1, ans = -1;
// f is a mapping.
// prime -> index in the current subarray
// With the help of f,
// we can detect whether a prime has
// already occurred in the subarray
for ( int i : v[0]) {
f[i] = 0;
}
while (l <= r && r < n) {
int flag = 0;
for ( int i = 0; i < v[r].size(); i++) {
// Map the prime to the index
if (f[v[r][i]] == -1 || f[v[r][i]] == r) {
f[v[r][i]] = r;
}
// If already occurred then,
// start removing elements from the left
else {
flag = 1;
break ;
}
}
// Remove elements if flag = 1
if (flag) {
// Nullify entries of element at index 'l'
for ( int i : v[l]) {
f[i] = -1;
}
// Increment 'l'
l++;
}
else {
// Maximize the answer when
// no common factor is found
ans = max(ans, r - l + 1);
r++;
}
}
// One length subarray is discarded
if (ans == 1)
ans = -1;
return ans;
} // Driver code int main()
{ sieve();
int arr[] = { 6, 10, 21 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxLengthSubArray(arr, n);
return 0;
} |
// Java implementation of the above approach import java.io.*;
import java.util.*;
class GFG{
static int N = 100005 ;
static int MAX = 1000002 ;
static int [] prime = new int [MAX];
// Stores array of primes for every element static ArrayList<
ArrayList<Integer>> v = new ArrayList<
ArrayList<Integer>>();
// Stores the position of a prime in the // subarray in two pointer technique static int [] f = new int [MAX];
// Function to store smallest prime // factor of numbers static void sieve()
{ for ( int i = 0 ; i < N; i++)
{
v.add( new ArrayList<Integer>());
}
prime[ 0 ] = prime[ 1 ] = 1 ;
for ( int i = 2 ; i < MAX; i++)
{
if (prime[i] == 0 )
{
for ( int j = i * 2 ; j < MAX; j += i)
{
if (prime[j] == 0 )
{
prime[j] = i;
}
}
}
}
for ( int i = 2 ; i < MAX; i++)
{
// If number is prime, then
// smallest prime factor is
// the number itself
if (prime[i] == 0 )
{
prime[i] = i;
}
}
} // Function to return maximum length of // subarray with LCM = product static int maxLengthSubArray( int [] arr, int n)
{ // Initialize f with -1
Arrays.fill(f, - 1 );
for ( int i = 0 ; i < n; ++i)
{
// Prime factorization of numbers
// Store primes in a vector for
// every element
while (arr[i] > 1 )
{
int p = prime[arr[i]];
arr[i] /= p;
v.get(i).add(p);
}
}
// Two pointers l and r denoting
// left and right of subarray
int l = 0 , r = 1 , ans = - 1 ;
// f is a mapping.
// prime -> index in the current subarray
// With the help of f,
// we can detect whether a prime has
// already occurred in the subarray
for ( int i : v.get( 0 ))
{
f[i] = 0 ;
}
while (l <= r && r < n)
{
int flag = 0 ;
for ( int i = 0 ; i < v.get(r).size(); i++)
{
// Map the prime to the index
if (f[v.get(r).get(i)] == - 1 ||
f[v.get(r).get(i)] == r)
{
f[v.get(r).get(i)] = r;
}
// If already occurred then,
// start removing elements
// from the left
else
{
flag = 1 ;
break ;
}
}
// Remove elements if flag = 1
if (flag != 0 )
{
// Nullify entries of element
// at index 'l'
for ( int i : v.get(l))
{
f[i] = - 1 ;
}
// Increment 'l'
l++;
}
else
{
// Maximize the answer when
// no common factor is found
ans = Math.max(ans, r - l + 1 );
r++;
}
}
// One length subarray is discarded
if (ans == 1 )
{
ans = - 1 ;
}
return ans;
} // Driver code public static void main(String[] args)
{ sieve();
int arr[] = { 6 , 10 , 21 };
int n = arr.length;
System.out.println(maxLengthSubArray(arr, n));
} } // This code is contributed by avanitrachhadiya2155 |
# Python3 implementation of the above approach N = 100005
MAX = 1000002
prime = [ 0 for i in range ( MAX + 1 )]
# Stores array of primes for every element v = [[] for i in range (N)]
# Stores the position of a prime in the subarray # in two pointer technique f = [ - 1 for i in range ( MAX )]
# Function to store smallest prime factor of numbers def sieve():
prime[ 0 ], prime[ 1 ] = 1 , 1
for i in range ( 2 , MAX + 1 ):
if (prime[i] = = 0 ):
for j in range (i * 2 , MAX , i):
if (prime[j] = = 0 ):
prime[j] = i
for i in range ( 2 , MAX ):
# If number is prime,
# then smallest prime factor is the
# number itself
if (prime[i] = = 0 ):
prime[i] = i
# Function to return maximum length of subarray # with LCM = product def maxLengthSubArray(arr, n):
# Initialize f with -1
for i in range (n):
f[i] = - 1
for i in range (n):
# Prime factorization of numbers
# Store primes in a vector for every element
while (arr[i] > 1 ):
p = prime[arr[i]]
arr[i] / / = p
v[i].append(p)
# Two pointers l and r
# denoting left and right of subarray
l, r, ans = 0 , 1 , - 1
# f is a mapping.
# prime -> index in the current subarray
# With the help of f,
# we can detect whether a prime has
# already occurred in the subarray
for i in v[ 0 ]:
f[i] = 0
while (l < = r and r < n):
flag = 0
for i in range ( len (v[r])):
# Map the prime to the index
if (f[v[r][i]] = = - 1 or f[v[r][i]] = = r):
f[v[r][i]] = r
# If already occurred then,
# start removing elements from the left
else :
flag = 1
break
# Remove elements if flag = 1
if (flag):
# Nullify entries of element at index 'l'
for i in v[l]:
f[i] = - 1
# Increment 'l'
l + = 1
else :
# Maximize the answer when
# no common factor is found
ans = max (ans, r - l + 1 )
r + = 1
# One length subarray is discarded
if (ans = = 1 ):
ans = - 1
return ans
# Driver code sieve() arr = [ 6 , 10 , 21 ]
n = len (arr)
print (maxLengthSubArray(arr, n))
# This code is contributed by mohit kumar |
// C# implementation of the above approach using System;
using System.Collections.Generic;
class GFG
{ static int N = 100005;
static int MAX = 1000002;
static int [] prime = new int [MAX];
// Stores array of primes for every element
static List<List< int >> v = new List<List< int >>();
// Stores the position of a prime in the
// subarray in two pointer technique
static int [] f = new int [MAX];
// Function to store smallest prime
// factor of numbers
static void sieve()
{
for ( int i = 0; i < N; i++)
{
v.Add( new List< int >());
}
prime[0] = prime[1] = 1;
for ( int i = 2; i < MAX; i++)
{
if (prime[i] == 0)
{
for ( int j = i * 2; j < MAX; j += i)
{
if (prime[j] == 0)
{
prime[j] = i;
}
}
}
}
for ( int i = 2; i < MAX; i++)
{
// If number is prime, then
// smallest prime factor is
// the number itself
if (prime[i] == 0)
{
prime[i] = i;
}
}
}
// Function to return maximum length of
// subarray with LCM = product
static int maxLengthSubArray( int [] arr, int n)
{
// Initialize f with -1
Array.Fill(f, -1);
for ( int i = 0; i < n; ++i)
{
// Prime factorization of numbers
// Store primes in a vector for
// every element
while (arr[i] > 1)
{
int p = prime[arr[i]];
arr[i] /= p;
v[i].Add(p);
}
}
// Two pointers l and r denoting
// left and right of subarray
int l = 0, r = 1, ans = -1;
// f is a mapping.
// prime -> index in the current subarray
// With the help of f,
// we can detect whether a prime has
// already occurred in the subarray
foreach ( int i in v[0])
{
f[i] = 0;
}
while (l <= r && r < n)
{
int flag = 0;
for ( int i = 0; i < v[r].Count; i++)
{
// Map the prime to the index
if (f[v[r][i]] == -1 ||
f[v[r][i]] == r)
{
f[v[r][i]] = r;
}
// If already occurred then,
// start removing elements
// from the left
else
{
flag = 1;
break ;
}
}
// Remove elements if flag = 1
if (flag != 0)
{
// Nullify entries of element
// at index 'l'
foreach ( int i in v[l])
{
f[i] = -1;
}
// Increment 'l'
l++;
}
else
{
// Maximize the answer when
// no common factor is found
ans = Math.Max(ans, r - l + 1);
r++;
}
}
// One length subarray is discarded
if (ans == 1)
{
ans = -1;
}
return ans;
}
// Driver code
static public void Main ()
{
sieve();
int [] arr = { 6, 10, 21 };
int n = arr.Length;
Console.WriteLine(maxLengthSubArray(arr, n));
}
} // This code is contributed by rag2127 |
<script> // Javascript implementation of the above approach let N = 100005; let MAX = 1000002; let prime = new Array(MAX);
for (let i=0;i<prime.length;i++)
{ prime[i]=0;
} // Stores array of primes for every element let v = []; // Stores the position of a prime in the // subarray in two pointer technique let f = new Array(MAX);
// Function to store smallest prime // factor of numbers function sieve()
{ for (let i = 0; i < N; i++)
{
v.push([]);
}
prime[0] = prime[1] = 1;
for (let i = 2; i < MAX; i++)
{
if (prime[i] == 0)
{
for (let j = i * 2; j < MAX; j += i)
{
if (prime[j] == 0)
{
prime[j] = i;
}
}
}
}
for (let i = 2; i < MAX; i++)
{
// If number is prime, then
// smallest prime factor is
// the number itself
if (prime[i] == 0)
{
prime[i] = i;
}
}
} // Function to return maximum length of // subarray with LCM = product function maxLengthSubArray(arr,n)
{ // Initialize f with -1
for (let i=0;i<f.length;i++)
{
f[i]=-1;
}
for (let i = 0; i < n; ++i)
{
// Prime factorization of numbers
// Store primes in a vector for
// every element
while (arr[i] > 1)
{
let p = prime[arr[i]];
arr[i] /= p;
v[i].push(p);
}
}
// Two pointers l and r denoting
// left and right of subarray
let l = 0, r = 1, ans = -1;
// f is a mapping.
// prime -> index in the current subarray
// With the help of f,
// we can detect whether a prime has
// already occurred in the subarray
for (let i=0;i< v[0].length;i++)
{
f[v[0][i]] = 0;
}
while (l <= r && r < n)
{
let flag = 0;
for (let i = 0; i < v[r].length; i++)
{
// Map the prime to the index
if (f[v[r][i]] == -1 ||
f[v[r][i]] == r)
{
f[v[r][i]] = r;
}
// If already occurred then,
// start removing elements
// from the left
else
{
flag = 1;
break ;
}
}
// Remove elements if flag = 1
if (flag != 0)
{
// Nullify entries of element
// at index 'l'
for (let i=0;i<v[l].length;i++)
{
f[v[l][i]] = -1;
}
// Increment 'l'
l++;
}
else
{
// Maximize the answer when
// no common factor is found
ans = Math.max(ans, r - l + 1);
r++;
}
}
// One length subarray is discarded
if (ans == 1)
{
ans = -1;
}
return ans;
} // Driver code sieve(); let arr=[ 6, 10, 21]; let n = arr.length; document.write(maxLengthSubArray(arr, n)); // This code is contributed by patel2127 </script> |
2