Maximize count of replaceable elements that can change initial GCD of Array
Last Updated :
26 Sep, 2022
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++
#include <bits/stdc++.h>
using namespace std;
int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
int func( int arr[], int N)
{
if (N == 1) {
return 1;
}
int counter = 0;
for ( int i = 0; i < N; i++) {
int gcd = 0;
for ( int j = 0; j < N; j++) {
if (i == j) {
continue ;
}
else {
gcd = GCD(gcd, arr[j]);
}
}
if (gcd > 1) {
counter++;
}
}
return counter;
}
int main()
{
int arr[] = { 5, 10, 15, 5 };
int N = 4;
int answer = func(arr, N);
cout << answer << "\n" ;
}
|
Java
import java.io.*;
class GFG {
public static void main(String[] args)
{
int [] arr = { 5 , 10 , 15 , 5 };
int N = arr.length;
int answer = func(arr, N);
System.out.println(answer);
}
static int func( int [] arr, int N)
{
if (N == 1 ) {
return 1 ;
}
int counter = 0 ;
for ( int i = 0 ; i < arr.length; i++) {
int gcd = 0 ;
for ( int j = 0 ; j < arr.length; j++) {
if (i == j) {
continue ;
}
else {
gcd = GCD(gcd, arr[j]);
}
}
if (gcd > 1 ) {
counter++;
}
}
return counter;
}
static int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
}
|
Python3
def func(arr, N):
if (N = = 1 ):
return 1
counter = 0
for i in range (N):
gcd = 0
for j in range (N):
if (i = = j):
continue
else :
gcd = GCD(gcd, arr[j])
if (gcd > 1 ):
counter + = 1
return counter
def GCD(a, b):
if (b = = 0 ):
return a
else :
return GCD(b, a % b)
arr = [ 5 , 10 , 15 , 5 ]
N = len (arr)
answer = func(arr, N)
print (answer)
|
C#
using System;
public class GFG {
static public void Main()
{
int [] arr = { 5, 10, 15, 5 };
int N = arr.Length;
int answer = func(arr, N);
Console.WriteLine(answer);
}
static int func( int [] arr, int N)
{
if (N == 1) {
return 1;
}
int counter = 0;
for ( int i = 0; i < arr.Length; i++) {
int gcd = 0;
for ( int j = 0; j < arr.Length; j++) {
if (i == j) {
continue ;
}
else {
gcd = GCD(gcd, arr[j]);
}
}
if (gcd > 1) {
counter++;
}
}
return counter;
}
static int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
}
|
Javascript
<script>
function GCD(a, b) {
return b == 0 ? a : GCD(b, a % b);
}
function func(arr, N) {
if (N == 1) {
return 1;
}
let counter = 0;
for (let i = 0; i < N; i++) {
let gcd = 0;
for (let j = 0; j < N; j++) {
if (i == j) {
continue ;
}
else {
gcd = GCD(gcd, arr[j]);
}
}
if (gcd > 1) {
counter++;
}
}
return counter;
}
let arr = [5, 10, 15, 5];
let N = 4;
let answer = func(arr, N);
document.write(answer + "<br>" );
</script>
|
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++
#include <algorithm>
#include <iostream>
using namespace std;
void solve( int arr[], int N)
{
if (N == 1) {
cout << 1;
return ;
}
int prefixGCD = 0;
pair< int , int > firstElement;
for ( int i = 0; i < N; i++) {
prefixGCD = __gcd(prefixGCD, arr[i]);
if (prefixGCD == 1) {
break ;
}
firstElement = make_pair(i, prefixGCD);
}
int suffixGCD = 0;
pair< int , int > lastElement;
for ( int i = N - 1; i >= 0; i--) {
suffixGCD = __gcd(suffixGCD, arr[i]);
if (suffixGCD == 1) {
break ;
}
lastElement = make_pair(i, suffixGCD);
}
if (prefixGCD != 1) {
cout << N;
}
else {
if (firstElement.first == lastElement.first) {
if (__gcd(firstElement.second,
lastElement.second)
== 1) {
cout << 0;
}
else {
cout << 1;
}
}
else {
cout << 0;
}
}
}
int main()
{
int arr[] = { 5, 10, 15, 20 };
int N = sizeof (arr) / sizeof (arr[0]);
solve(arr, N);
return 0;
}
|
Java
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 (N == 1 ) {
System.out.print( 1 );
return ;
}
int prefixGCD = 0 ;
int firstElement[] = new int [ 2 ];
for ( int i = 0 ; i < N; i++) {
prefixGCD = gcd(prefixGCD, arr[i]);
if (prefixGCD == 1 ) {
break ;
}
firstElement[ 0 ] = i;
firstElement[ 1 ] = prefixGCD;
}
int suffixGCD = 0 ;
int lastElement[] = new int [ 2 ];
for ( int i = N - 1 ; i >= 0 ; i--) {
suffixGCD = gcd(suffixGCD, arr[i]);
if (suffixGCD == 1 ) {
break ;
}
lastElement[ 0 ] = i;
lastElement[ 1 ] = suffixGCD;
}
if (prefixGCD != 1 ) {
System.out.print(N);
}
else {
if (firstElement[ 0 ] == lastElement[ 0 ]) {
if (gcd(firstElement[ 1 ], lastElement[ 1 ])
== 1 ) {
System.out.print( 0 );
}
else {
System.out.print( 1 );
}
}
else {
System.out.print( 0 );
}
}
}
public static void main(String[] args)
{
int arr[] = { 5 , 10 , 15 , 20 };
int N = 4 ;
solve(arr, N);
}
}
|
Python3
def gcd(a, b):
if b is 0 :
return a
return gcd(b, a % b)
def solve(arr, N):
if N is 1 :
print ( 1 )
return
prefixGCD = 0
firstElement = [ 0 ] * 2
for i in range (N):
prefixGCD = gcd(prefixGCD, arr[i])
if prefixGCD is 1 :
break
firstElement[ 0 ] = i
firstElement[ 1 ] = prefixGCD
suffixGCD = 0
lastElement = [ 0 ] * 2
for i in range (N - 1 , 0 , - 1 ):
suffixGCD = gcd(suffixGCD, arr[i])
if suffixGCD is 1 :
break
lastElement[ 0 ] = i
lastElement[ 1 ] = suffixGCD
if prefixGCD is not 1 :
print (N)
else :
if firstElement[ 0 ] is lastElement[ 0 ]:
if gcd(firstElement[ 1 ], lastElement[ 1 ]) is True :
print ( 0 )
else :
print ( 1 )
else :
print ( 0 )
arr = [ 5 , 10 , 15 , 20 ]
N = 4
solve(arr, N)
|
C#
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 (N == 1) {
Console.Write(1);
return ;
}
int prefixGCD = 0;
int [] firstElement = new int [2];
for ( int i = 0; i < N; i++) {
prefixGCD = gcd(prefixGCD, arr[i]);
if (prefixGCD == 1) {
break ;
}
firstElement[0] = i;
firstElement[1] = prefixGCD;
}
int suffixGCD = 0;
int [] lastElement = new int [2];
for ( int i = N - 1; i >= 0; i--) {
suffixGCD = gcd(suffixGCD, arr[i]);
if (suffixGCD == 1) {
break ;
}
lastElement[0] = i;
lastElement[1] = suffixGCD;
}
if (prefixGCD != 1) {
Console.Write(N);
}
else {
if (firstElement[0] == lastElement[0]) {
if (gcd(firstElement[1], lastElement[1])
== 1) {
Console.Write(0);
}
else {
Console.Write(1);
}
}
else {
Console.Write(0);
}
}
}
public static void Main()
{
int [] arr = { 5, 10, 15, 20 };
int N = 4;
solve(arr, N);
}
}
|
Javascript
<script>
function gcd(a, b)
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}
function solve(arr, N)
{
if (N == 1) {
document.write(1);
return ;
}
let prefixGCD = 0;
let firstElement = new Array(2);
for (let i = 0; i < N; i++) {
prefixGCD = gcd(prefixGCD, arr[i]);
if (prefixGCD == 1) {
break ;
}
firstElement[0] = i;
firstElement[1] = prefixGCD;
}
let suffixGCD = 0;
let lastElement = new Array(2);
for (let i = N - 1; i >= 0; i--) {
suffixGCD = gcd(suffixGCD, arr[i]);
if (suffixGCD == 1) {
break ;
}
lastElement[0] = i;
lastElement[1] = suffixGCD;
}
if (prefixGCD != 1) {
document.write(N);
}
else {
if (firstElement[0] == lastElement[0]) {
if (gcd(firstElement[1], lastElement[1])
== 1) {
document.write(0);
}
else {
document.write(1);
}
}
else {
document.write(0);
}
}
}
let arr = [ 5, 10, 15, 20 ];
let N = 4;
solve(arr, N);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...