Open In App

Maximize count of replaceable elements that can change initial GCD of Array

Last Updated : 26 Sep, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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>


Output

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>


Output

4

Time Complexity: O(N)
Auxiliary Space: O(1) 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads