Count ways to split array into two subarrays with equal GCD
Last Updated :
22 Nov, 2021
Given an array, arr[] of size N, the task is to count the number of ways to split given array elements into two subarrays such that GCD of both the subarrays are equal.
Examples:
Input: arr[] = {8, 4, 4, 8, 12}
Output: 2
Explanation:
Possible ways to split the array two groups of equal GCD are: { {{arr[0], arr[1]}, {arr[2], arr[3], arr[4]}}, {{arr[0], arr[1], arr[2]}, {arr[3], arr[4]}} }.
Therefore, the required output is 2.
Input: arr[] = {1, 2, 4, 6, 5}
Output: 2
Naive Approach: The simplest approach to solve this problem is to traverse the array and at each array index, partition the array into two subarrays and check if the GCD of both the subarrays are equal or not. If found to be true, then increment the count of such subarrays. Finally, print the count.
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach, the idea is to use Prefix Sum Array technique. Follow the steps below to solve the problem:
- Initialize a variable, say cntWays to store count of ways to split the array into two subarrays such that GCD of both the subarrays are equal.
- Initialize an array, say prefixGCD[] to store the prefix GCD of array elements.
- Initialize an array, say suffixGCD[] to store the suffix GCD of array elements.
- Traverse prefixGCD[] and suffixGCD[] arrays using variable i and check if prefixGCD[i] and suffixGCD[i + 1] are equal or not. If found to be true, then increment the value of cntWays.
- Finally, print the value of cntWays.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int cntWaysToSplitArrayTwo( int arr[], int N)
{
int prefixGCD[N];
prefixGCD[0] = arr[0];
int suffixGCD[N];
suffixGCD[N - 1] = arr[N - 1];
for ( int i = 1; i < N; i++) {
prefixGCD[i]
= __gcd(prefixGCD[i - 1],
arr[i]);
}
for ( int i = N - 2; i >= 0; i--) {
suffixGCD[i]
= __gcd(suffixGCD[i + 1],
arr[i]);
}
int cntWays = 0;
for ( int i = 0; i < N - 1; i++) {
if (prefixGCD[i]
== suffixGCD[i + 1]) {
cntWays += 1;
}
}
return cntWays;
}
int main()
{
int arr[] = { 8, 4, 4, 8, 12 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << cntWaysToSplitArrayTwo(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
static int gcd( int a, int b)
{
if (a == 0 )
return b;
if (b == 0 )
return a;
if (a == b)
return a;
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
static int cntWaysToSplitArrayTwo( int arr[],
int N)
{
int prefixGCD[] = new int [N];
prefixGCD[ 0 ] = arr[ 0 ];
int suffixGCD[] = new int [N];
suffixGCD[N - 1 ] = arr[N - 1 ];
for ( int i = 1 ; i < N; i++)
{
prefixGCD[i] = gcd(prefixGCD[i - 1 ],
arr[i]);
}
for ( int i = N - 2 ; i >= 0 ; i--)
{
suffixGCD[i] = gcd(suffixGCD[i + 1 ],
arr[i]);
}
int cntWays = 0 ;
for ( int i = 0 ; i < N - 1 ; i++)
{
if (prefixGCD[i] == suffixGCD[i + 1 ])
{
cntWays += 1 ;
}
}
return cntWays;
}
public static void main(String[] args)
{
int arr[] = { 8 , 4 , 4 , 8 , 12 };
int N = arr.length;
System.out.print(cntWaysToSplitArrayTwo(arr, N));
}
}
|
Python3
import math
def cntWaysToSplitArrayTwo(arr, N):
prefixGCD = [ 0 ] * N
prefixGCD[ 0 ] = arr[ 0 ]
suffixGCD = [ 0 ] * N
suffixGCD[N - 1 ] = arr[N - 1 ]
for i in range (N):
prefixGCD[i] = math.gcd(prefixGCD[i - 1 ], arr[i])
for i in range (N - 2 , - 1 , - 1 ):
suffixGCD[i] = math.gcd(suffixGCD[i + 1 ], arr[i])
cntWays = 0
for i in range (N - 1 ):
if (prefixGCD[i] = = suffixGCD[i + 1 ]):
cntWays + = 1
return cntWays
arr = [ 8 , 4 , 4 , 8 , 12 ]
N = len (arr)
print (cntWaysToSplitArrayTwo(arr, N))
|
C#
using System;
class GFG{
static int gcd( int a, int b)
{
if (a == 0)
return b;
if (b == 0)
return a;
if (a == b)
return a;
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
static int cntWaysToSplitArrayTwo( int []arr,
int N)
{
int []prefixGCD = new int [N];
prefixGCD[0] = arr[0];
int []suffixGCD = new int [N];
suffixGCD[N - 1] = arr[N - 1];
for ( int i = 1; i < N; i++)
{
prefixGCD[i] = gcd(prefixGCD[i - 1],
arr[i]);
}
for ( int i = N - 2; i >= 0; i--)
{
suffixGCD[i] = gcd(suffixGCD[i + 1],
arr[i]);
}
int cntWays = 0;
for ( int i = 0; i < N - 1; i++)
{
if (prefixGCD[i] == suffixGCD[i + 1])
{
cntWays += 1;
}
}
return cntWays;
}
public static void Main(String[] args)
{
int []arr = { 8, 4, 4, 8, 12 };
int N = arr.Length;
Console.Write(cntWaysToSplitArrayTwo(arr, N));
}
}
|
Javascript
<script>
function gcd(a, b)
{
if (a == 0)
return b;
if (b == 0)
return a;
if (a == b)
return a;
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
function cntWaysToSplitArrayTwo(arr, N)
{
let prefixGCD = [];
prefixGCD[0] = arr[0];
let suffixGCD = [];
suffixGCD[N - 1] = arr[N - 1];
for (let i = 1; i < N; i++)
{
prefixGCD[i] = gcd(prefixGCD[i - 1],
arr[i]);
}
for (let i = N - 2; i >= 0; i--)
{
suffixGCD[i] = gcd(suffixGCD[i + 1],
arr[i]);
}
let cntWays = 0;
for (let i = 0; i < N - 1; i++)
{
if (prefixGCD[i] == suffixGCD[i + 1])
{
cntWays += 1;
}
}
return cntWays;
}
let arr = [ 8, 4, 4, 8, 12 ];
let N = arr.length;
document.write(cntWaysToSplitArrayTwo(arr, N));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...