Given an array arr[] of length N ≥ 2. The task is to remove an element from the given array such that the GCD of the array after removing it is maximized.
Examples:
Input: arr[] = {12, 15, 18}
Output: 6
Remove 12: GCD(15, 18) = 3
Remove 15: GCD(12, 18) = 6
Remove 18: GCD(12, 15) = 3Input: arr[] = {14, 17, 28, 70}
Output: 14
Approach:
- Idea is to find the GCD value of all the sub-sequences of length (N – 1) and removing the element which is not present in the sub-sequence with that GCD. The maximum GCD found would be the answer.
- To find the GCD of the sub-sequences optimally, maintain a prefixGCD[] and a suffixGCD[] array using single state dynamic programming.
- The maximum value of GCD(prefixGCD[i – 1], suffixGCD[i + 1]) is the required answer.
Below is the implementation of the above approach:
CPP
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std; // Function to return the maximized gcd // after removing a single element // from the given array int MaxGCD( int a[], int n) { // Prefix and Suffix arrays int Prefix[n + 2]; int Suffix[n + 2]; // Single state dynamic programming relation // for storing gcd of first i elements // from the left in Prefix[i] Prefix[1] = a[0]; for ( int i = 2; i <= n; i += 1) { Prefix[i] = __gcd(Prefix[i - 1], a[i - 1]); } // Initializing Suffix array Suffix[n] = a[n - 1]; // Single state dynamic programming relation // for storing gcd of all the elements having // greater than or equal to i in Suffix[i] for ( int i = n - 1; i >= 1; i -= 1) { Suffix[i] = __gcd(Suffix[i + 1], a[i - 1]); } // If first or last element of // the array has to be removed int ans = max(Suffix[2], Prefix[n - 1]); // If any other element is replaced for ( int i = 2; i < n; i += 1) { ans = max(ans, __gcd(Prefix[i - 1], Suffix[i + 1])); } // Return the maximized gcd return ans; } // Driver code int main() { int a[] = { 14, 17, 28, 70 }; int n = sizeof (a) / sizeof (a[0]); cout << MaxGCD(a, n); return 0; } |
Java
// Java implementation of the above approach class Test { // Recursive function to return gcd of a and b static int gcd( int a, int b) { if (b == 0 ) return a; return gcd(b, a % b); } // Function to return the maximized gcd // after removing a single element // from the given array static int MaxGCD( int a[], int n) { // Prefix and Suffix arrays int Prefix[] = new int [n + 2 ]; int Suffix[] = new int [n + 2 ] ; // Single state dynamic programming relation // for storing gcd of first i elements // from the left in Prefix[i] Prefix[ 1 ] = a[ 0 ]; for ( int i = 2 ; i <= n; i += 1 ) { Prefix[i] = gcd(Prefix[i - 1 ], a[i - 1 ]); } // Initializing Suffix array Suffix[n] = a[n - 1 ]; // Single state dynamic programming relation // for storing gcd of all the elements having // greater than or equal to i in Suffix[i] for ( int i = n - 1 ; i >= 1 ; i -= 1 ) { Suffix[i] = gcd(Suffix[i + 1 ], a[i - 1 ]); } // If first or last element of // the array has to be removed int ans = Math.max(Suffix[ 2 ], Prefix[n - 1 ]); // If any other element is replaced for ( int i = 2 ; i < n; i += 1 ) { ans = Math.max(ans, gcd(Prefix[i - 1 ], Suffix[i + 1 ])); } // Return the maximized gcd return ans; } // Driver code public static void main(String[] args) { int a[] = { 14 , 17 , 28 , 70 }; int n = a.length; System.out.println(MaxGCD(a, n)); } } // This code is contributed by AnkitRai01 |
Python3
# Python3 implementation of the above approach import math as mt # Function to return the maximized gcd # after removing a single element # from the given array def MaxGCD(a, n): # Prefix and Suffix arrays Prefix = [ 0 for i in range (n + 2 )] Suffix = [ 0 for i in range (n + 2 )] # Single state dynamic programming relation # for storing gcd of first i elements # from the left in Prefix[i] Prefix[ 1 ] = a[ 0 ] for i in range ( 2 ,n + 1 ): Prefix[i] = mt.gcd(Prefix[i - 1 ], a[i - 1 ]) # Initializing Suffix array Suffix[n] = a[n - 1 ] # Single state dynamic programming relation # for storing gcd of all the elements having # greater than or equal to i in Suffix[i] for i in range (n - 1 , 0 , - 1 ): Suffix[i] = mt.gcd(Suffix[i + 1 ], a[i - 1 ]) # If first or last element of # the array has to be removed ans = max (Suffix[ 2 ], Prefix[n - 1 ]) # If any other element is replaced for i in range ( 2 ,n): ans = max (ans, mt.gcd(Prefix[i - 1 ], Suffix[i + 1 ])) # Return the maximized gcd return ans # Driver code a = [ 14 , 17 , 28 , 70 ] n = len (a) print (MaxGCD(a, n)) # This code is contributed by mohit kumar 29 |
C#
// C# implementation of the above approach using System; class GFG { // Recursive function to return gcd of a and b static int gcd( int a, int b) { if (b == 0) return a; return gcd(b, a % b); } // Function to return the maximized gcd // after removing a single element // from the given array static int MaxGCD( int []a, int n) { // Prefix and Suffix arrays int []Prefix = new int [n + 2]; int []Suffix = new int [n + 2] ; // Single state dynamic programming relation // for storing gcd of first i elements // from the left in Prefix[i] Prefix[1] = a[0]; for ( int i = 2; i <= n; i += 1) { Prefix[i] = gcd(Prefix[i - 1], a[i - 1]); } // Initializing Suffix array Suffix[n] = a[n - 1]; // Single state dynamic programming relation // for storing gcd of all the elements having // greater than or equal to i in Suffix[i] for ( int i = n - 1; i >= 1; i -= 1) { Suffix[i] = gcd(Suffix[i + 1], a[i - 1]); } // If first or last element of // the array has to be removed int ans = Math.Max(Suffix[2], Prefix[n - 1]); // If any other element is replaced for ( int i = 2; i < n; i += 1) { ans = Math.Max(ans, gcd(Prefix[i - 1], Suffix[i + 1])); } // Return the maximized gcd return ans; } // Driver code static public void Main () { int []a = { 14, 17, 28, 70 }; int n = a.Length; Console.Write(MaxGCD(a, n)); } } // This code is contributed by ajit. |
14
Time Complexity: O(N * log(M)) where M is the maximum element from the array.
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.