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++
// 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
// 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
# 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#
// 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 // 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 ?> |
Javascript
<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++
// 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
// 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
# 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#
// 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 |
Javascript
<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
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!