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:
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++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to find all starting and // ending indices of all windows static void All_windows( int arr[], int n,
vector< int > &start,
vector< int > &end, int X)
{ // left start_index of window
// initialized to zero
int start_index = 0;
// Loop for traversing
// on input arr[]
while (start_index < n)
{
// If any element found such
// that it is not completely
// divisible by X
if (arr[start_index] % X != 0)
{
// Incrementing start_index
start_index++;
}
// If any element found such
// that it is completely
// divisible by X, Then else
// part will be execute
else
{
// end_index initialized
// to zero
int end_index = start_index;
// Incrementing end_index
// while next element is
// completely divisible by X
while (end_index < n - 1 && arr[end_index + 1] % X == 0)
end_index = end_index + 1;
// Adding start index of
// window in start list
start.push_back(start_index);
// push_backing end index of
// window in end list
end.push_back(end_index);
start_index = end_index + 1;
}
}
} // Euclidean algorithm to return // GCD of two integers int GCD( int a, int b)
{ return b == 0 ? a : GCD(b, a % b);
} // Function to find maximum number of // adjacent subarrays satisfying the condition int maxSubarrays( int arr[], int n, int X)
{ // List declared to store Input
// all starting indices of Window
vector< int > start;
// List declared to store all
// ending indices of window
vector< int > end;
// Function to store start and end
// indices of all windows
All_windows(arr, n, start, end, X);
// Variable to store maximum value
// of adjacent sub-arrays.
int max = 0;
// Loop for traversing on all
// Windows present in arr[]
for ( int i = 0; i < start.size(); i++)
{
// Starting index of window
int start_index = start[i];
// Ending index of window
int end_index = end[i];
// Counter to store maximum
// adjacent sub-array in
// window
int counter = 0;
// Variable to store current
// GCD while traversing
// on window
int current_gcd = 0;
// Loop for traversing on
// current window
for ( int j = start_index; j <= end_index; j++)
{
// updating value of
// current_gcd variable by
// calculating GCD
current_gcd = GCD(current_gcd, arr[j]);
// Condition when GCD is
// Equal to X
if (current_gcd == X)
{
// Incrementing value
// of counter
counter++;
// Setting back
// current_gcd to zero
current_gcd = 0;
}
}
// Updating value of Max
max = counter > max ? counter : max;
}
return max;
} // Driver code int main()
{ int N = 6;
int arr[] = {5, 10, 1, 5, 10, 5};
int X = 5;
// Function call
cout << (maxSubarrays(arr, N, X));
} // This code is contributed by Potta Lokesh |
// Java code to implement the approach import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
// Driver code
public static void main(String[] args)
{
int N = 6 ;
int [] arr = { 5 , 10 , 1 , 5 , 10 , 5 };
int X = 5 ;
// Function call
System.out.println(maxSubarrays(arr, N, X));
}
// Function to find maximum number of
// adjacent subarrays satisfying the condition
static int maxSubarrays( int arr[], int n, int X)
{
// List initialized to store Input
// all starting indices of Window
ArrayList<Integer> start = new ArrayList<>();
// List initialized to store all
// ending indices of window
ArrayList<Integer> end = new ArrayList<>();
// Function to store start and end
// indices of all windows
All_windows(arr, n, start, end, X);
// Variable to store maximum value
// of adjacent sub-arrays.
int max = 0 ;
// Loop for traversing on all
// Windows present in arr[]
for ( int i = 0 ; i < start.size(); i++) {
// Starting index of window
int start_index = start.get(i);
// Ending index of window
int end_index = end.get(i);
// Counter to store maximum
// adjacent sub-array in
// window
int counter = 0 ;
// Variable to store current
// GCD while traversing
// on window
int current_gcd = 0 ;
// Loop for traversing on
// current window
for ( int j = start_index; j <= end_index; j++) {
// updating value of
// current_gcd variable by
// calculating GCD
current_gcd = GCD(current_gcd, arr[j]);
// Condition when GCD is
// Equal to X
if (current_gcd == X) {
// Incrementing value
// of counter
counter++;
// Setting back
// current_gcd to zero
current_gcd = 0 ;
}
}
// Updating value of Max
max = counter > max ? counter : max;
}
return max;
}
// Function to find all starting and
// ending indices of all windows
static void All_windows( int arr[], int n,
ArrayList<Integer> start,
ArrayList<Integer> end, int X)
{
// left start_index of window
// initialized to zero
int start_index = 0 ;
// Loop for traversing
// on input arr[]
while (start_index < n) {
// If any element found such
// that it is not completely
// divisible by X
if (arr[start_index] % X != 0 ) {
// Incrementing start_index
start_index++;
}
// If any element found such
// that it is completely
// divisible by X, Then else
// part will be execute
else {
// end_index initialized
// to zero
int end_index = start_index;
// Incrementing end_index
// while next element is
// completely divisible by X
while (end_index < n - 1
&& arr[end_index + 1 ] % X == 0 )
end_index = end_index + 1 ;
// Adding start index of
// window in start list
start.add(start_index);
// Adding end index of
// window in end list
end.add(end_index);
start_index = end_index + 1 ;
}
}
}
// Euclidean algorithm to return
// GCD of two integers
static int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
} |
# Python3 code to implement the above approach # Function to find all starting and # ending indices of all windows def All_windows(arr, n,start,end, X) :
# left start_index of window
# initialized to zero
start_index = 0 ;
# Loop for traversing
# on input arr[]
while (start_index < n) :
# If any element found such
# that it is not completely
# divisible by X
if (arr[start_index] % X ! = 0 ) :
# Incrementing start_index
start_index + = 1 ;
# If any element found such
# that it is completely
# divisible by X, Then else
# part will be execute
else :
# end_index initialized
# to zero
end_index = start_index;
# Incrementing end_index
# while next element is
# completely divisible by X
while (end_index < n - 1 and arr[end_index + 1 ] % X = = 0 ) :
end_index = end_index + 1 ;
# Adding start index of
# window in start list
start.append(start_index);
# push_backing end index of
# window in end list
end.append(end_index);
start_index = end_index + 1 ;
return start,end
# Euclidean algorithm to return # GCD of two integers def GCD(a, b) :
if b = = 0 :
return a
else :
return GCD(b, a % b)
# Function to find maximum number of # adjacent subarrays satisfying the condition def maxSubarrays(arr, n, X) :
# List declared to store Input
# all starting indices of Window
start = [];
# List declared to store all
# ending indices of window
end = [];
# Function to store start and end
# indices of all windows
start,end = All_windows(arr, n, start, end, X);
# Variable to store maximum value
# of adjacent sub-arrays.
max = 0 ;
# Loop for traversing on all
# Windows present in arr[]
for i in range ( len (start)) :
# Starting index of window
start_index = start[i];
# Ending index of window
end_index = end[i];
# Counter to store maximum
# adjacent sub-array in
# window
counter = 0 ;
# Variable to store current
# GCD while traversing
# on window
current_gcd = 0 ;
# Loop for traversing on
# current window
for j in range (start_index, end_index + 1 ) :
# updating value of
# current_gcd variable by
# calculating GCD
current_gcd = GCD(current_gcd, arr[j]);
# Condition when GCD is
# Equal to X
if (current_gcd = = X) :
# Incrementing value
# of counter
counter + = 1 ;
# Setting back
# current_gcd to zero
current_gcd = 0 ;
# Updating value of Max
if counter > max :
max = counter;
else :
max = max
return max ;
# Driver code if __name__ = = "__main__" :
N = 6 ;
arr = [ 5 , 10 , 1 , 5 , 10 , 5 ];
X = 5 ;
# Function call
print (maxSubarrays(arr, N, X));
# This code is contributed by AnkThon
|
// C# code to implement the approach using System;
using System.Collections.Generic;
public class GFG {
// Function to find maximum number of
// adjacent subarrays satisfying the condition
static int maxSubarrays( int [] arr, int n, int X)
{
// List initialized to store Input
// all starting indices of Window
List< int > start = new List< int >();
// List initialized to store all
// ending indices of window
List< int > end = new List< int >();
// Function to store start and end
// indices of all windows
All_windows(arr, n, start, end, X);
// Variable to store maximum value
// of adjacent sub-arrays.
int max = 0;
// Loop for traversing on all
// Windows present in arr[]
for ( int i = 0; i < start.Count; i++) {
// Starting index of window
int start_index = start[i];
// Ending index of window
int end_index = end[i];
// Counter to store maximum
// adjacent sub-array in
// window
int counter = 0;
// Variable to store current
// GCD while traversing
// on window
int current_gcd = 0;
// Loop for traversing on
// current window
for ( int j = start_index; j <= end_index; j++) {
// updating value of
// current_gcd variable by
// calculating GCD
current_gcd = GCD(current_gcd, arr[j]);
// Condition when GCD is
// Equal to X
if (current_gcd == X) {
// Incrementing value
// of counter
counter++;
// Setting back
// current_gcd to zero
current_gcd = 0;
}
}
// Updating value of Max
max = counter > max ? counter : max;
}
return max;
}
// Function to find all starting and
// ending indices of all windows
static void All_windows( int [] arr, int n,
List< int > start, List< int > end,
int X)
{
// left start_index of window
// initialized to zero
int start_index = 0;
// Loop for traversing
// on input arr[]
while (start_index < n) {
// If any element found such
// that it is not completely
// divisible by X
if (arr[start_index] % X != 0) {
// Incrementing start_index
start_index++;
}
// If any element found such
// that it is completely
// divisible by X, Then else
// part will be execute
else {
// end_index initialized
// to zero
int end_index = start_index;
// Incrementing end_index
// while next element is
// completely divisible by X
while (end_index < n - 1
&& arr[end_index + 1] % X == 0)
end_index = end_index + 1;
// Adding start index of
// window in start list
start.Add(start_index);
// Adding end index of
// window in end list
end.Add(end_index);
start_index = end_index + 1;
}
}
}
// Euclidean algorithm to return
// GCD of two integers
static int GCD( int a, int b)
{
return b == 0 ? a : GCD(b, a % b);
}
// Driver Code
static public void Main()
{
int N = 6;
int [] arr = { 5, 10, 1, 5, 10, 5 };
int X = 5;
// Function call
Console.WriteLine(maxSubarrays(arr, N, X));
}
} // This code is contributed by Rohit Pradhan |
<script> // JavaScript code for the above approach
// Function to find maximum number of // adjacent subarrays satisfying the condition
function maxSubarrays(arr, n, X)
{
// List initialized to store Input
// all starting indices of Window
start = [];
// List initialized to store all
// ending indices of window
end = [];
// Function to store start and end
// indices of all windows
All_windows(arr, n, start, end, X);
// Variable to store maximum value
// of adjacent sub-arrays.
let max = 0;
// Loop for traversing on all
// Windows present in arr[]
for (let i = 0; i < start.length; i++) {
// Starting index of window
let start_index = start[i];
// Ending index of window
let end_index = end[i];
// Counter to store maximum
// adjacent sub-array in
// window
let counter = 0;
// Variable to store current
// GCD while traversing
// on window
let current_gcd = 0;
// Loop for traversing on
// current window
for (let j = start_index; j <= end_index; j++) {
// updating value of
// current_gcd variable by
// calculating GCD
current_gcd = GCD(current_gcd, arr[j]);
// Condition when GCD is
// Equal to X
if (current_gcd == X) {
// Incrementing value
// of counter
counter++;
// Setting back
// current_gcd to zero
current_gcd = 0;
}
}
// Updating value of Max
max = counter > max ? counter : max;
}
return max;
}
// Function to find all starting and
// ending indices of all windows
function All_windows(arr, n, start, end, X)
{
// left start_index of window
// initialized to zero
let start_index = 0;
// Loop for traversing
// on input arr[]
while (start_index < n) {
// If any element found such
// that it is not completely
// divisible by X
if (arr[start_index] % X != 0) {
// Incrementing start_index
start_index++;
}
// If any element found such
// that it is completely
// divisible by X, Then else
// part will be execute
else {
// end_index initialized
// to zero
let end_index = start_index;
// Incrementing end_index
// while next element is
// completely divisible by X
while (end_index < n - 1
&& arr[end_index + 1] % X == 0)
end_index = end_index + 1;
// Adding start index of
// window in start list
start.push(start_index);
// Adding end index of
// window in end list
end.push(end_index);
start_index = end_index + 1;
}
}
}
// Euclidean algorithm to return
// GCD of two integers
function GCD(a, b)
{
return b == 0 ? a : GCD(b, a % b);
}
// Driver code
let N = 6;
let arr = [ 5, 10, 1, 5, 10, 5 ];
let X = 5;
// Function call
document.write(maxSubarrays(arr, N, X));
// This code is contributed by code_hunt. </script> |
2
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.