Maximize count of replaceable elements that can change initial GCD of Array
Given an integer array A[] of length N (N >= 1), the task is to print the total number of indices in the array that can be used to modify the GCD of the whole array just by replacing elements at that index with any other positive integer.
Examples:
Input: arr[] = {5, 10, 20}
Output: 3
Explanation : All the three indices can be replaced with 1 to alter the GCD of whole array to 1.Input: arr[] = { 5, 7, 11}
Output: 0
Explanation: No array elements can be replaced that can alter the GCD of whole array as the GCD is 1.Input: arr[] = {2, 2, 2, 2}
Output: 4
Approach: To solve the problem use the following idea
For each index calculate the GCD of whole array excluding element at that index. If GCD comes out to 1, then don’t count that index for your answer. If GCD comes out greater than 1 then count that index for your answer.
Because if GCD is greater than 1, So that you can change GCD to 1 by replacing 1 with element at that index, otherwise if GCD comes already 1, so you can’t change GCD by placing any positive integer at that index.
Illustration :
Consider array arr[] = {2,4,5,8},Iterate once from left to right on arr[] and apply following operation : –
- for index 0 : Calculate GCD of arr[] excluding element at index 0, Which is 1
- for index 1 : Calculate GCD of arr[] excluding element at index 1, Which is 1
- for index 2 : Calculate GCD of arr[] excluding element at index 2, Which is 2
- for index 3 : Calculate GCD of arr[] excluding element at index 3, Which is 1,
We has traversed all array, Now just print total no. of indices on which we get GCD greater than 1.
Here GCD is greater than 1 only at index 2.Therefore, answer to this test case is 1.
Follow the steps to solve the problem:
- If there is only one element return 1 else traverse the array and for each array element do the following operations
- Create a counter variable initialized with 0 to store the answer
- Calculate the GCD of the whole array except the current element index.
- If the GCD comes out to 1 then continue
- Else increment the counter
- Return the final answer stored on the counter
- Print the answer
Below is the implementation of this approach :
C++
// C++ code to implement this approach #include <bits/stdc++.h> using namespace std; // Euclidean algorithm to return GCD int GCD(int a, int b) { return b == 0 ? a : GCD(b, a % b); } int func(int arr[], int N) { // if only a single element if (N == 1) { return 1; } // counter to store no. of indices int counter = 0; // Loop to traverse each element for (int i = 0; i < N; i++) { // Variable to store GCD int gcd = 0; // Loop to calculate GCD for (int j = 0; j < N; j++) { // Excluding current element if (i == j) { continue; } else { // Function Call for GCD gcd = GCD(gcd, arr[j]); } } // if GCD of remaining elements is greater than 1. if (gcd > 1) { // Updating the counter counter++; } } // returning the answer return counter; } // Driver Code int main() { // Given input int arr[] = { 5, 10, 15, 5 }; int N = 4; // Calling the function int answer = func(arr, N); // Printing the answer cout << answer << "\n"; } // This code is contributed by ajaymakvana.
Java
// Java code for the above approach import java.io.*; class GFG { // Driver Code public static void main(String[] args) { // Given input int[] arr = { 5, 10, 15, 5 }; int N = arr.length; // Calling the function int answer = func(arr, N); // Printing the answer System.out.println(answer); } static int func(int[] arr, int N) { // if only a single element if (N == 1) { return 1; } // counter to store no. of indices int counter = 0; // Loop to traverse each element for (int i = 0; i < arr.length; i++) { // Variable to store GCD int gcd = 0; // Loop to calculate GCD for (int j = 0; j < arr.length; j++) { // Excluding current element if (i == j) { continue; } else { // Function Call for GCD gcd = GCD(gcd, arr[j]); } } // if GCD of remaining elements // is greater than 1. if (gcd > 1) { // Updating the counter counter++; } } // returning the answer return counter; } // Euclidean algorithm to return GCD static int GCD(int a, int b) { return b == 0 ? a : GCD(b, a % b); } }
Python3
# Python3 code for the above approach def func(arr, N): if(N == 1): return 1 # counter to store no. of indices counter = 0 # loop to traverse each element for i in range(N): # variable to store GCD gcd = 0 # loop to calculate GCD for j in range(N): # excluding current element if(i == j): continue else: # Function call for GCD gcd = GCD(gcd, arr[j]) # if GCD of remaining elements is greater than 1. if(gcd > 1): # updating the counter counter += 1 # returning the answer return counter # Euclidean algorithm to return GCD def GCD(a, b): if(b == 0): return a else: return GCD(b, a % b) arr = [5, 10, 15, 5] N = len(arr) # Function call answer = func(arr, N) # Print the answer print(answer) # This code is contributed by lokeshmvs21.
C#
// C# code for the above approach using System; public class GFG { static public void Main() { // Given input int[] arr = { 5, 10, 15, 5 }; int N = arr.Length; // Calling the function int answer = func(arr, N); // Printing the answer Console.WriteLine(answer); } static int func(int[] arr, int N) { // if only a single element if (N == 1) { return 1; } // counter to store no. of indices int counter = 0; // Loop to traverse each element for (int i = 0; i < arr.Length; i++) { // Variable to store GCD int gcd = 0; // Loop to calculate GCD for (int j = 0; j < arr.Length; j++) { // Excluding current element if (i == j) { continue; } else { // Function Call for GCD gcd = GCD(gcd, arr[j]); } } // if GCD of remaining elements // is greater than 1. if (gcd > 1) { // Updating the counter counter++; } } // returning the answer return counter; } // Euclidean algorithm to return GCD static int GCD(int a, int b) { return b == 0 ? a : GCD(b, a % b); } } // This code is contributed by lokeshmvs21.
Javascript
<script> // Javascript code to implement this approach // Euclidean algorithm to return GCD function GCD(a, b) { return b == 0 ? a : GCD(b, a % b); } function func(arr, N) { // if only a single element if (N == 1) { return 1; } // counter to store no. of indices let counter = 0; // Loop to traverse each element for (let i = 0; i < N; i++) { // Variable to store GCD let gcd = 0; // Loop to calculate GCD for (let j = 0; j < N; j++) { // Excluding current element if (i == j) { continue; } else { // Function Call for GCD gcd = GCD(gcd, arr[j]); } } // if GCD of remaining elements is greater than 1. if (gcd > 1) { // Updating the counter counter++; } } // returning the answer return counter; } // Driver Code // Given input let arr = [5, 10, 15, 5]; let N = 4; // Calling the function let answer = func(arr, N); // Printing the answer document.write(answer + "<br>"); // This code is contributed by Saurabh Jaiswal. </script>
4
Time Complexity: O(N ^ 2 * log(max(Arr[i]))), where max(Arr[i]) is the maximum element in the array.
Auxiliary Space: O(1)
Efficient Approach: To optimize the approach using the following idea:
There are 3 scenarios, GCD of whole array is greater than 1, so the answer is N. The GCD of whole array is 1 but if one element is removed then the GCD becomes greater than 1, so the answer is 1. The GCD of whole array is 1 but it requires removing more than two elements to make the GCD greater than one so the answer will be 0.
Follow the below steps to solve the problem:
- Check if there is only 1 element then the answer is 1 and return
- Create element prefixGCD = 0 to store the GCD of the element from the front and pair<int, int> firstElement to store the GCD of front elements until it becomes 1.
- Calculate prefixGCD in the array and update firstElement until all the elements are traversed or the GCD becomes 1.
- Create element suffixGCD = 0 to store the GCD of the element from the back and pair<int, int> lastElement to store the GCD of end elements until it becomes 1.
- Calculate suffixGCD in the array and update lastElement until all the elements are traversed or the GCD becomes 1.
- If prefixGCD is greater than 1 then print N as the answer.
- If prefixGCD has 1 then, if the same element is making the GCD 1 from the front and back check indices stores in firstElement and lastElement
- if not then print 0 as the answer
- else if the GCD’s stored in firstElement and secondElement has a GCD 1 then print 0
- else print 1
Below is the implementation of the given approach:
C++
// C++ code for the above approach #include <algorithm> #include <iostream> using namespace std; void solve(int arr[], int N) { // if there is single element // then answer is 1 if (N == 1) { cout << 1; return; } // variable to store the GCD // from front int prefixGCD = 0; // variable to store the index // of element making GCD as 1 pair<int, int> firstElement; for (int i = 0; i < N; i++) { // Updating prefixGCD prefixGCD = __gcd(prefixGCD, arr[i]); // Terminate if GCD has become 1 if (prefixGCD == 1) { break; } // Update the first element with // GCD greater than 1 firstElement = make_pair(i, prefixGCD); } // variable to store the GCD // from end int suffixGCD = 0; // variable to store the index // of element making GCD as 1 pair<int, int> lastElement; for (int i = N - 1; i >= 0; i--) { // Updating suffixGCD suffixGCD = __gcd(suffixGCD, arr[i]); // Terminate if GCD has become 1 if (suffixGCD == 1) { break; } // Update the last element with // GCD greater than 1 lastElement = make_pair(i, suffixGCD); } // if the GCD of whole array is // greater than 1 if (prefixGCD != 1) { cout << N; } else { // if same element is making GCD as 1 if (firstElement.first == lastElement.first) { // if the remaining has a GCD 1 // then answer is 0 else 1 if (__gcd(firstElement.second, lastElement.second) == 1) { cout << 0; } else { cout << 1; } } else { cout << 0; } } } // Driver Code int main() { // Given input int arr[] = { 5, 10, 15, 20 }; int N = sizeof(arr) / sizeof(arr[0]); // Function call solve(arr, N); return 0; }
Java
// Java code for the above approach import java.io.*; class GFG { public static int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } public static void solve(int arr[], int N) { // if there is single element // then answer is 1 if (N == 1) { System.out.print(1); return; } // variable to store the GCD // from front int prefixGCD = 0; // variable to store the index // of element making GCD as 1 int firstElement[] = new int[2]; for (int i = 0; i < N; i++) { // Updating prefixGCD prefixGCD = gcd(prefixGCD, arr[i]); // Terminate if GCD has become 1 if (prefixGCD == 1) { break; } // Update the first element with // GCD greater than 1 firstElement[0] = i; firstElement[1] = prefixGCD; } // variable to store the GCD // from end int suffixGCD = 0; // variable to store the index // of element making GCD as 1 int lastElement[] = new int[2]; for (int i = N - 1; i >= 0; i--) { // Updating suffixGCD suffixGCD = gcd(suffixGCD, arr[i]); // Terminate if GCD has become 1 if (suffixGCD == 1) { break; } // Update the last element with // GCD greater than 1 lastElement[0] = i; lastElement[1] = suffixGCD; } // if the GCD of whole array is // greater than 1 if (prefixGCD != 1) { System.out.print(N); } else { // if same element is making GCD as 1 if (firstElement[0] == lastElement[0]) { // if the remaining has a GCD 1 // then answer is 0 else 1 if (gcd(firstElement[1], lastElement[1]) == 1) { System.out.print(0); } else { System.out.print(1); } } else { System.out.print(0); } } } // Driver Code public static void main(String[] args) { // Given input int arr[] = { 5, 10, 15, 20 }; int N = 4; // Function call solve(arr, N); } } // This code is contributed by Rohit Pradhan
Python3
# Python Code for the above approach def gcd(a, b): if b is 0: return a return gcd(b, a % b) def solve(arr, N): # If there is single element then answer is 1 if N is 1: print(1) return # Variable to store the GCD from front prefixGCD = 0 # Variable to store the index of element making GCD as 1 firstElement = [0] * 2 for i in range(N): # Updating prefixGCD prefixGCD = gcd(prefixGCD, arr[i]) # Terminate if GCD has become 1 if prefixGCD is 1: break # Update the first element with GCD greater than 1 firstElement[0] = i firstElement[1] = prefixGCD # Variable to store the GCD from end suffixGCD = 0 # Variable to store the index of element making GCD as 1 lastElement = [0]*2 for i in range(N-1, 0, -1): # Updating suffixGCD suffixGCD = gcd(suffixGCD, arr[i]) # Terminate if GCD has become 1 if suffixGCD is 1: break # Update the last element with GCD greater than 1 lastElement[0] = i lastElement[1] = suffixGCD # If the GCD of whole array is greater than 1 if prefixGCD is not 1: print(N) else: # If same element is making GCD as 1 if firstElement[0] is lastElement[0]: # If the remaining has a GCD 1 then answer is 0 else 1 if gcd(firstElement[1], lastElement[1]) is True: print(0) else: print(1) else: print(0) arr = [5, 10, 15, 20] N = 4 # Function call solve(arr, N) # This code is contributed by lokeshmvs21.
C#
// C# code to implement the approach using System; class GFG { public static int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } public static void solve(int[] arr, int N) { // if there is single element // then answer is 1 if (N == 1) { Console.Write(1); return; } // variable to store the GCD // from front int prefixGCD = 0; // variable to store the index // of element making GCD as 1 int[] firstElement = new int[2]; for (int i = 0; i < N; i++) { // Updating prefixGCD prefixGCD = gcd(prefixGCD, arr[i]); // Terminate if GCD has become 1 if (prefixGCD == 1) { break; } // Update the first element with // GCD greater than 1 firstElement[0] = i; firstElement[1] = prefixGCD; } // variable to store the GCD // from end int suffixGCD = 0; // variable to store the index // of element making GCD as 1 int[] lastElement = new int[2]; for (int i = N - 1; i >= 0; i--) { // Updating suffixGCD suffixGCD = gcd(suffixGCD, arr[i]); // Terminate if GCD has become 1 if (suffixGCD == 1) { break; } // Update the last element with // GCD greater than 1 lastElement[0] = i; lastElement[1] = suffixGCD; } // if the GCD of whole array is // greater than 1 if (prefixGCD != 1) { Console.Write(N); } else { // if same element is making GCD as 1 if (firstElement[0] == lastElement[0]) { // if the remaining has a GCD 1 // then answer is 0 else 1 if (gcd(firstElement[1], lastElement[1]) == 1) { Console.Write(0); } else { Console.Write(1); } } else { Console.Write(0); } } } // Driver Code public static void Main() { // Given input int[] arr = { 5, 10, 15, 20 }; int N = 4; // Function call solve(arr, N); } } // This code is contributed by sanjoy_62.
Javascript
<script> // JavaScript code for the approach function gcd(a, b) { if (b == 0) return a; else return gcd(b, a % b); } function solve(arr, N) { // if there is single element // then answer is 1 if (N == 1) { document.write(1); return; } // variable to store the GCD // from front let prefixGCD = 0; // variable to store the index // of element making GCD as 1 let firstElement = new Array(2); for (let i = 0; i < N; i++) { // Updating prefixGCD prefixGCD = gcd(prefixGCD, arr[i]); // Terminate if GCD has become 1 if (prefixGCD == 1) { break; } // Update the first element with // GCD greater than 1 firstElement[0] = i; firstElement[1] = prefixGCD; } // variable to store the GCD // from end let suffixGCD = 0; // variable to store the index // of element making GCD as 1 let lastElement = new Array(2); for (let i = N - 1; i >= 0; i--) { // Updating suffixGCD suffixGCD = gcd(suffixGCD, arr[i]); // Terminate if GCD has become 1 if (suffixGCD == 1) { break; } // Update the last element with // GCD greater than 1 lastElement[0] = i; lastElement[1] = suffixGCD; } // if the GCD of whole array is // greater than 1 if (prefixGCD != 1) { document.write(N); } else { // if same element is making GCD as 1 if (firstElement[0] == lastElement[0]) { // if the remaining has a GCD 1 // then answer is 0 else 1 if (gcd(firstElement[1], lastElement[1]) == 1) { document.write(0); } else { document.write(1); } } else { document.write(0); } } } // Driver code // Given input let arr = [ 5, 10, 15, 20 ]; let N = 4; // Function call solve(arr, N); // This code is contributed by code_hunt. </script>
4
Time Complexity: O(N)
Auxiliary Space: O(1)
Please Login to comment...