Open In App

Maximum number of adjacent Subarrays having GCD X

Last Updated : 14 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// 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




// 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




# 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#




// 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


Javascript




<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>


Output

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.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads