Maximum number of adjacent Subarrays having GCD X
Last Updated :
14 Apr, 2023
Given an array arr[] of length N consisting of positive integers and an integer X, the task is to find the maximum number of adjacent Sub-Arrays by following all the given conditions:
- Each Sub-Array should have GCD equal to X.
- One element can be a part of only one sub-Array.
Note: If there is only one subarray satisfying all given conditions and has no adjacent subarrays, then the maximum number of subarrays will be counted as 1.
Examples:
Input: N = 6, arr[] = {5, 10, 1, 5, 10, 5}, X = 5
Output: 2
Explanation: 2 Sub-Arrays are possible from index 3 to 3
and 4 to 5 which are {5} and {10, 5} respectively.
They both are adjacent to each other as well as there is no element
in both the Sub-arrays that is a part of both Sub-arrays.
So the maximum number of subarrays is 2.
Input: N = 4, arr[] = {1, 4, 3, 1}, X = 1
Output: 3
Explanation: The three subarrays are {1}, {4, 3}, {1}
Input: N = 2, arr[] = {5, 10}, X = 5
Output: 1
Explanation: Only one subarray has GCD 5. i.e., {5}.
Notice {5, 10} subarray also has GCD 5 but it cannot be counted because
then 5 will become part of two subarrays.
Approach: To solve the problem follow the below idea:
Problem can be solved by finding all windows in arr[] such that all elements of a window is perfectly divisible by X. Traverse on each window and calculate GCD in a variable let’s say current_gcd . If current_gcd is equal to X then increment counter and set current_gcd = 0.Print the Maximum number of adjacent Sub-Arrays after applying approach on each window.
Illustration of approach:
Consider an example N = 6, arr[] = {2, 18, 2, 5, 1, 2} and X = 2
Explanation with approach:
All possible continuous windows such that each element of windows is divided by X
There are Two possible windows that are shown in the picture for start and ending indexes as (0, 2) and (5, 5) respectively. Let’s apply the approach on both of them for Finding Maximum Sub-Arrays satisfying conditions:
In Window1 from index 0 to 2:
Create a counter variable and initialize it to zero, Traverse on window and calculate GCD in variable, let’s say current_gcd.
- Till index 0, current_gcd= 2, which is equal to X, Hence increment counter to 1 and set current_gcd to 0.
- Till index 1, current_gcd = 18 , which is not equal to X, Hence counter and current_gcd remains same.
- Till index 2, current_gcd= 2, which is equal to X, hence increment counter to 2 and set current_gcd to 0
Maximum number of Sub-arrays satisfying given conditions are 2 for this window, Which are {2} and {18, 2}, Both are adjacent and have GCD = 2 along with no same indexed element belongs to Both Sub-Arrays.
In Window 2 from index 5 to 5:
- There is only one element in the array which is 2, Hence only 1 Sub-Array possible which is {2}.
- Therefore, Maximum number of Sub-Arrays are = 1.
Maximum possible adjacent Sub-Arrays among all windows is = 2.
Follow the steps to solve the problem:
- Find all windows such that each element of the window is completely divisible by X.
- Find all start and end indices of the windows and store them in two lists let’s say start and end create a variable max to store the maximum number of adjacent Sub-arrays.
- Traverse on each window by finding the start and end indices of all windows stored in two lists in the previous step and Follow the below-mentioned steps for each window:
- Create variable current_gcd and counter-initialize them to zero.
- Calculate GCD while traversing on window and update the value of current_gcd.
- If current_gcd equal to X, Then increment counter and set current_gcd to 0.
- After traversing the whole window, Update the max if the counter is greater than the max.
- Print the value of max.
Below is the implementation for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
static void All_windows( int arr[], int n,
vector< int > &start,
vector< int > &end, int X)
{
int start_index = 0;
while (start_index < n)
{
if (arr[start_index] % X != 0)
{
start_index++;
}
else
{
int end_index = start_index;
while (end_index < n - 1 && arr[end_index + 1] % X == 0)
end_index = end_index + 1;
start.push_back(start_index);
end.push_back(end_index);
start_index = end_index + 1;
}
}
}
int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
int maxSubarrays( int arr[], int n, int X)
{
vector< int > start;
vector< int > end;
All_windows(arr, n, start, end, X);
int max = 0;
for ( int i = 0; i < start.size(); i++)
{
int start_index = start[i];
int end_index = end[i];
int counter = 0;
int current_gcd = 0;
for ( int j = start_index; j <= end_index; j++)
{
current_gcd = GCD(current_gcd, arr[j]);
if (current_gcd == X)
{
counter++;
current_gcd = 0;
}
}
max = counter > max ? counter : max;
}
return max;
}
int main()
{
int N = 6;
int arr[] = {5, 10, 1, 5, 10, 5};
int X = 5;
cout << (maxSubarrays(arr, N, X));
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
public static void main(String[] args)
{
int N = 6 ;
int [] arr = { 5 , 10 , 1 , 5 , 10 , 5 };
int X = 5 ;
System.out.println(maxSubarrays(arr, N, X));
}
static int maxSubarrays( int arr[], int n, int X)
{
ArrayList<Integer> start = new ArrayList<>();
ArrayList<Integer> end = new ArrayList<>();
All_windows(arr, n, start, end, X);
int max = 0 ;
for ( int i = 0 ; i < start.size(); i++) {
int start_index = start.get(i);
int end_index = end.get(i);
int counter = 0 ;
int current_gcd = 0 ;
for ( int j = start_index; j <= end_index; j++) {
current_gcd = GCD(current_gcd, arr[j]);
if (current_gcd == X) {
counter++;
current_gcd = 0 ;
}
}
max = counter > max ? counter : max;
}
return max;
}
static void All_windows( int arr[], int n,
ArrayList<Integer> start,
ArrayList<Integer> end, int X)
{
int start_index = 0 ;
while (start_index < n) {
if (arr[start_index] % X != 0 ) {
start_index++;
}
else {
int end_index = start_index;
while (end_index < n - 1
&& arr[end_index + 1 ] % X == 0 )
end_index = end_index + 1 ;
start.add(start_index);
end.add(end_index);
start_index = end_index + 1 ;
}
}
}
static int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
}
|
Python3
def All_windows(arr, n,start,end, X) :
start_index = 0 ;
while (start_index < n) :
if (arr[start_index] % X ! = 0 ) :
start_index + = 1 ;
else :
end_index = start_index;
while (end_index < n - 1 and arr[end_index + 1 ] % X = = 0 ) :
end_index = end_index + 1 ;
start.append(start_index);
end.append(end_index);
start_index = end_index + 1 ;
return start,end
def GCD(a, b) :
if b = = 0 :
return a
else :
return GCD(b, a % b)
def maxSubarrays(arr, n, X) :
start = [];
end = [];
start,end = All_windows(arr, n, start, end, X);
max = 0 ;
for i in range ( len (start)) :
start_index = start[i];
end_index = end[i];
counter = 0 ;
current_gcd = 0 ;
for j in range (start_index, end_index + 1 ) :
current_gcd = GCD(current_gcd, arr[j]);
if (current_gcd = = X) :
counter + = 1 ;
current_gcd = 0 ;
if counter > max :
max = counter;
else :
max = max
return max ;
if __name__ = = "__main__" :
N = 6 ;
arr = [ 5 , 10 , 1 , 5 , 10 , 5 ];
X = 5 ;
print (maxSubarrays(arr, N, X));
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int maxSubarrays( int [] arr, int n, int X)
{
List< int > start = new List< int >();
List< int > end = new List< int >();
All_windows(arr, n, start, end, X);
int max = 0;
for ( int i = 0; i < start.Count; i++) {
int start_index = start[i];
int end_index = end[i];
int counter = 0;
int current_gcd = 0;
for ( int j = start_index; j <= end_index; j++) {
current_gcd = GCD(current_gcd, arr[j]);
if (current_gcd == X) {
counter++;
current_gcd = 0;
}
}
max = counter > max ? counter : max;
}
return max;
}
static void All_windows( int [] arr, int n,
List< int > start, List< int > end,
int X)
{
int start_index = 0;
while (start_index < n) {
if (arr[start_index] % X != 0) {
start_index++;
}
else {
int end_index = start_index;
while (end_index < n - 1
&& arr[end_index + 1] % X == 0)
end_index = end_index + 1;
start.Add(start_index);
end.Add(end_index);
start_index = end_index + 1;
}
}
}
static int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
static public void Main()
{
int N = 6;
int [] arr = { 5, 10, 1, 5, 10, 5 };
int X = 5;
Console.WriteLine(maxSubarrays(arr, N, X));
}
}
|
Javascript
<script>
function maxSubarrays(arr, n, X)
{
start = [];
end = [];
All_windows(arr, n, start, end, X);
let max = 0;
for (let i = 0; i < start.length; i++) {
let start_index = start[i];
let end_index = end[i];
let counter = 0;
let current_gcd = 0;
for (let j = start_index; j <= end_index; j++) {
current_gcd = GCD(current_gcd, arr[j]);
if (current_gcd == X) {
counter++;
current_gcd = 0;
}
}
max = counter > max ? counter : max;
}
return max;
}
function All_windows(arr, n, start, end, X)
{
let start_index = 0;
while (start_index < n) {
if (arr[start_index] % X != 0) {
start_index++;
}
else {
let end_index = start_index;
while (end_index < n - 1
&& arr[end_index + 1] % X == 0)
end_index = end_index + 1;
start.push(start_index);
end.push(end_index);
start_index = end_index + 1;
}
}
}
function GCD(a, b)
{
return b == 0 ? a : GCD(b, a % b);
}
let N = 6;
let arr = [ 5, 10, 1, 5, 10, 5 ];
let X = 5;
document.write(maxSubarrays(arr, N, X));
</script>
|
Time Complexity: O(N)
- Getting all window’s start and end indices takes O(N) and the maximum size of the window can be equal to the whole array itself.
- In this case, we can get all adjacent sub-Array by a single traversal of the array, therefore, Complexity will be O(N).
Auxiliary Space: O(N), As start and end Array-Lists are used to store indices of all windows.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...