Longest subarray with GCD greater than 1 - GeeksforGeeks

05 Oct, 2021
Given an array arr[] consisting of N integers, the task is to find the maximum length of subarray having the Greatest Common Divisor (GCD) of all the elements greater than 1.
Examples:
Input: arr[] = {4, 3, 2, 2}Output: 2Explaination:Consider the subarray {2, 2} having GCD as 2(> 1) which is of maximum length.
Input: arr[] = {410, 52, 51, 180, 222, 33, 33}Output: 5
Naive Approach: The given problem can be solved by generating all possible subarrays of the given array and keep track of the maximum length of the subarray with GCD greater than 1. After checking for all the subarrays, print the maximum length obtained.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program of the above approach#include <bits/stdc++.h>using namespace std; // Function to find maximum length of// the subarray having GCD > onevoid maxSubarrayLen(int arr[], int n){    // Stores maximum length of subarray    int maxLen = 0;     // Loop to iterate over all subarrays    // starting from index i    for (int i = 0; i < n; i++) {         // Find the GCD of subarray        // from i to j        int gcd = 0;        for (int j = i; j < n; j++) {             // Calculate GCD            gcd = __gcd(gcd, arr[j]);             // Update maximum length            // of the subarray            if (gcd > 1)                maxLen = max(maxLen, j - i + 1);            else                break;        }    }     // Print maximum length    cout << maxLen;} // Driver Codeint main(){    int arr[] = { 410, 52, 51, 180,                  222, 33, 33 };    int N = sizeof(arr) / sizeof(int);    maxSubarrayLen(arr, N);     return 0;}
// Java code for above approachimport java.util.*; class GFG{     // Recursive function to return gcd of a and b    static int __gcd(int a, int b)    {        // Everything divides 0        if (a == 0)          return b;        if (b == 0)          return a;               // base case        if (a == b)            return a;               // a is greater        if (a > b)            return __gcd(a-b, b);        return __gcd(a, b-a);    }     // Function to find maximum length of// the subarray having GCD > onestatic void maxSubarrayLen(int arr[], int n){    // Stores maximum length of subarray    int maxLen = 0;     // Loop to iterate over all subarrays    // starting from index i    for (int i = 0; i < n; i++) {         // Find the GCD of subarray        // from i to j        int gcd = 0;        for (int j = i; j < n; j++) {             // Calculate GCD            gcd = __gcd(gcd, arr[j]);             // Update maximum length            // of the subarray            if (gcd > 1)                maxLen = Math.max(maxLen, j - i + 1);            else                break;        }    }     // Print maximum length    System.out.print(maxLen);}  // Driver Codepublic static void main(String[] args) {    int arr[] = { 410, 52, 51, 180,                  222, 33, 33 };    int N = arr.length;    maxSubarrayLen(arr, N);}} // This code is contributed by avijitmondal1998.
# Python program of the above approachdef __gcd(a, b):  if (b == 0): return a;  return __gcd(b, a % b);  # Function to find maximum length of# the subarray having GCD > onedef maxSubarrayLen(arr, n) :   # Stores maximum length of subarray  maxLen = 0;   # Loop to iterate over all subarrays  # starting from index i  for i in range(n):       # Find the GCD of subarray    # from i to j    gcd = 0;    for j in range(i, n):           # Calculate GCD      gcd = __gcd(gcd, arr[j]);       # Update maximum length      # of the subarray      if (gcd > 1):           maxLen = max(maxLen, j - i + 1);      else: break;       # Print maximum length  print(maxLen); # Driver Codearr = [410, 52, 51, 180, 222, 33, 33];N = len(arr)maxSubarrayLen(arr, N); # This code is contributed by gfgking.
// C# code for the above approachusing System;using System.Collections.Generic;public class GFG{   // Function to find maximum length of  // the subarray having GCD > one  static int __gcd(int a, int b)  {     // Everything divides 0    if (a == 0)      return b;    if (b == 0)      return a;     // base case    if (a == b)      return a;     // a is greater    if (a > b)      return __gcd(a - b, b);     return __gcd(a, b - a);  }  static void maxSubarrayLen(int []arr, int n)  {     // Stores maximum length of subarray    int maxLen = 0;     // Loop to iterate over all subarrays    // starting from index i    for (int i = 0; i < n; i++) {       // Find the GCD of subarray      // from i to j      int gcd = 0;      for (int j = i; j < n; j++) {         // Calculate GCD        gcd = __gcd(gcd, arr[j]);         // Update maximum length        // of the subarray        if (gcd > 1)          maxLen = Math.Max(maxLen, j - i + 1);        else          break;      }    }     // Print maximum length    Console.Write(maxLen);  }   // Driver Code  static public void Main (){    int []arr = { 410, 52, 51, 180,                 222, 33, 33 };    int N = arr.Length;    maxSubarrayLen(arr, N);  }} // This code is contributed by Potta Lokesh
<script>// Javascript program of the above approachfunction __gcd(a, b) {  if (b == 0) return a;  return __gcd(b, a % b);} // Function to find maximum length of// the subarray having GCD > onefunction maxSubarrayLen(arr, n){   // Stores maximum length of subarray  let maxLen = 0;   // Loop to iterate over all subarrays  // starting from index i  for (let i = 0; i < n; i++)  {       // Find the GCD of subarray    // from i to j    let gcd = 0;    for (let j = i; j < n; j++)    {           // Calculate GCD      gcd = __gcd(gcd, arr[j]);       // Update maximum length      // of the subarray      if (gcd > 1) maxLen = Math.max(maxLen, j - i + 1);      else break;    }  }   // Print maximum length  document.write(maxLen);} // Driver Codelet arr = [410, 52, 51, 180, 222, 33, 33];let N = arr.length;maxSubarrayLen(arr, N); // This code is contributed by _saurabh_jaiswal.</script>
  
5
 
 
Time Complexity: O(N2)Auxiliary Space: O(1)
 
Efficient Approach: The above can also be optimized using the Sliding Window Technique and Segment Tree. Suppose L denotes the first index, R denotes the last index and X denotes the size of the current window, then there are two possible cases as discussed below:
 
The GCD of the current window is 1. In this case, move to the next window of size X (i.e. L + 1 to R + 1).
The GCD of the current window is greater than 1. In this case, increase the size of the current window by one, (i.e., L to R + 1).
 
Therefore, to implement the above idea, a Segment Tree can be used to find the GCD of the given index ranges of the array efficiently.
 
Below is the implementation of the above approach:
 
C++
Java
Python3
C#
Javascript
// C++ program of the above approach#include <bits/stdc++.h>using namespace std; // Function to build the Segment Tree// from the given array to process// range queries in log(N) timevoid build_tree(int* b, vector<int>& seg_tree,                int l, int r, int vertex){    // Termination Condition    if (l == r) {        seg_tree[vertex] = b[l];        return;    }     // Find the mid value    int mid = (l + r) / 2;     // Left and Right  Recursive Call    build_tree(b, seg_tree, l, mid,               2 * vertex);    build_tree(b, seg_tree, mid + 1,               r, 2 * vertex + 1);     // Update the Segment Tree Node    seg_tree[vertex] = __gcd(seg_tree[2 * vertex],                             seg_tree[2 * vertex + 1]);} // Function to return the GCD of the// elements of the Array from index// l to index rint range_gcd(vector<int>& seg_tree, int v,              int tl, int tr,              int l, int r){    // Base Case    if (l > r)        return 0;    if (l == tl && r == tr)        return seg_tree[v];     // Find the middle range    int tm = (tl + tr) / 2;     // Find the GCD and return    return __gcd(        range_gcd(seg_tree, 2 * v, tl,                  tm, l, min(tm, r)),         range_gcd(seg_tree, 2 * v + 1,                  tm + 1, tr,                  max(tm + 1, l), r));} // Function to print maximum length of// the subarray having GCD > onevoid maxSubarrayLen(int arr[], int n){    // Stores the Segment Tree    vector<int> seg_tree(4 * (n) + 1, 0);     // Function call to build the    // Segment tree from array arr[]    build_tree(arr, seg_tree, 0, n - 1, 1);     // Store maximum length of subarray    int maxLen = 0;     // Starting and ending pointer of    // the current window    int l = 0, r = 0;     while (r < n && l < n) {         // Case where the GCD of the        // current window is 1        if (range_gcd(seg_tree, 1, 0,                      n - 1, l, r)            == 1) {            l++;        }         // Update the maximum length        maxLen = max(maxLen, r - l + 1);        r++;    }     // Print answer    cout << maxLen;} // Driver Codeint main(){    int arr[] = { 410, 52, 51, 180, 222, 33, 33 };    int N = sizeof(arr) / sizeof(int);    maxSubarrayLen(arr, N);     return 0;}
// Java program of the above approachclass GFG{ // Function to build the Segment Tree// from the given array to process// range queries in log(N) timestatic void build_tree(int[] b, int [] seg_tree,                int l, int r, int vertex){       // Termination Condition    if (l == r) {        seg_tree[vertex] = b[l];        return;    }     // Find the mid value    int mid = (l + r) / 2;     // Left and Right  Recursive Call    build_tree(b, seg_tree, l, mid,               2 * vertex);    build_tree(b, seg_tree, mid + 1,               r, 2 * vertex + 1);     // Update the Segment Tree Node    seg_tree[vertex] = __gcd(seg_tree[2 * vertex],                             seg_tree[2 * vertex + 1]);}static int __gcd(int a, int b) {     return b == 0? a:__gcd(b, a % b);    }   // Function to return the GCD of the// elements of the Array from index// l to index rstatic int range_gcd(int [] seg_tree, int v,              int tl, int tr,              int l, int r){    // Base Case    if (l > r)        return 0;    if (l == tl && r == tr)        return seg_tree[v];     // Find the middle range    int tm = (tl + tr) / 2;     // Find the GCD and return    return __gcd(        range_gcd(seg_tree, 2 * v, tl,                  tm, l, Math.min(tm, r)),         range_gcd(seg_tree, 2 * v + 1,                  tm + 1, tr,                  Math.max(tm + 1, l), r));} // Function to print maximum length of// the subarray having GCD > onestatic void maxSubarrayLen(int arr[], int n){    // Stores the Segment Tree    int []seg_tree = new int[4 * (n) + 1];     // Function call to build the    // Segment tree from array arr[]    build_tree(arr, seg_tree, 0, n - 1, 1);     // Store maximum length of subarray    int maxLen = 0;     // Starting and ending pointer of    // the current window    int l = 0, r = 0;     while (r < n && l < n) {         // Case where the GCD of the        // current window is 1        if (range_gcd(seg_tree, 1, 0,                      n - 1, l, r)            == 1) {            l++;        }         // Update the maximum length        maxLen = Math.max(maxLen, r - l + 1);        r++;    }     // Print answer    System.out.print(maxLen);} // Driver Codepublic static void main(String[] args){    int arr[] = { 410, 52, 51, 180, 222, 33, 33 };    int N = arr.length;    maxSubarrayLen(arr, N); }} // This code is contributed by shikhasingrajput
# Python3 program of the above approach # Function to build the Segment Tree# from the given array to process# range queries in log(N) timedef build_tree(b, seg_tree, l, r, vertex):    # Termination Condition    if (l == r):        seg_tree[vertex] = b[l]        return      # Find the mid value    mid = int((l + r) / 2)      # Left and Right  Recursive Call    build_tree(b, seg_tree, l, mid, 2 * vertex)    build_tree(b, seg_tree, mid + 1, r, 2 * vertex + 1)      # Update the Segment Tree Node    seg_tree[vertex] = __gcd(seg_tree[2 * vertex], seg_tree[2 * vertex + 1]) def __gcd(a, b):    if b == 0:        return b    else:        return __gcd(b, a % b)    # Function to return the GCD of the# elements of the Array from index# l to index rdef range_gcd(seg_tree, v, tl, tr, l, r):    # Base Case    if (l > r):        return 0    if (l == tl and r == tr):        return seg_tree[v]      # Find the middle range    tm = int((tl + tr) / 2)      # Find the GCD and return    return __gcd(range_gcd(seg_tree, 2 * v, tl, tm, l, min(tm, r)),        range_gcd(seg_tree, 2 * v + 1, tm + 1, tr, max(tm + 1, l), r))  # Function to print maximum length of# the subarray having GCD > onedef maxSubarrayLen(arr, n):    # Stores the Segment Tree    seg_tree = [0]*(4*n + 1)      # Function call to build the    # Segment tree from array []arr    build_tree(arr, seg_tree, 0, n - 1, 1)      # Store maximum length of subarray    maxLen = 0      # Starting and ending pointer of    # the current window    l, r = 0, 0      while (r < n and l < n):        # Case where the GCD of the        # current window is 1        if (range_gcd(seg_tree, 1, 0, n - 1, l, r) == 1):            l+=1          # Update the maximum length        maxLen = max(maxLen, r - l - 1)        r+=1      # Print answer    print(maxLen, end = "") arr = [ 410, 52, 51, 180, 222, 33, 33 ]N = len(arr)maxSubarrayLen(arr, N) # This code is contributed by divyesh072019.
// C# program of the above approachusing System;public class GFG{ // Function to build the Segment Tree// from the given array to process// range queries in log(N) timestatic void build_tree(int[] b, int [] seg_tree,                int l, int r, int vertex){       // Termination Condition    if (l == r) {        seg_tree[vertex] = b[l];        return;    }     // Find the mid value    int mid = (l + r) / 2;     // Left and Right  Recursive Call    build_tree(b, seg_tree, l, mid,               2 * vertex);    build_tree(b, seg_tree, mid + 1,               r, 2 * vertex + 1);     // Update the Segment Tree Node    seg_tree[vertex] = __gcd(seg_tree[2 * vertex],                             seg_tree[2 * vertex + 1]);}static int __gcd(int a, int b) {     return b == 0? a:__gcd(b, a % b);    }   // Function to return the GCD of the// elements of the Array from index// l to index rstatic int range_gcd(int [] seg_tree, int v,              int tl, int tr,              int l, int r){    // Base Case    if (l > r)        return 0;    if (l == tl && r == tr)        return seg_tree[v];     // Find the middle range    int tm = (tl + tr) / 2;     // Find the GCD and return    return __gcd(        range_gcd(seg_tree, 2 * v, tl,                  tm, l, Math.Min(tm, r)),         range_gcd(seg_tree, 2 * v + 1,                  tm + 1, tr,                  Math.Max(tm + 1, l), r));} // Function to print maximum length of// the subarray having GCD > onestatic void maxSubarrayLen(int []arr, int n){    // Stores the Segment Tree    int []seg_tree = new int[4 * (n) + 1];     // Function call to build the    // Segment tree from array []arr    build_tree(arr, seg_tree, 0, n - 1, 1);     // Store maximum length of subarray    int maxLen = 0;     // Starting and ending pointer of    // the current window    int l = 0, r = 0;     while (r < n && l < n) {         // Case where the GCD of the        // current window is 1        if (range_gcd(seg_tree, 1, 0,                      n - 1, l, r)            == 1) {            l++;        }         // Update the maximum length        maxLen = Math.Max(maxLen, r - l + 1);        r++;    }     // Print answer    Console.Write(maxLen);} // Driver Codepublic static void Main(String[] args){    int []arr = { 410, 52, 51, 180, 222, 33, 33 };    int N = arr.Length;    maxSubarrayLen(arr, N); }} // This code is contributed by shikhasingrajput
<script>// Javascript program of the above approach function __gcd(a, b) {  if (b == 0) return a;  return __gcd(b, a % b);} // Function to build the Segment Tree// from the given array to process// range queries in log(N) timefunction build_tree(b, seg_tree, l, r, vertex) {  // Termination Condition  if (l == r) {    seg_tree[vertex] = b[l];    return;  }   // Find the mid value  let mid = Math.floor((l + r) / 2);   // Left and Right  Recursive Call  build_tree(b, seg_tree, l, mid, 2 * vertex);  build_tree(b, seg_tree, mid + 1, r, 2 * vertex + 1);   // Update the Segment Tree Node  seg_tree[vertex] = __gcd(seg_tree[2 * vertex], seg_tree[2 * vertex + 1]);} // Function to return the GCD of the// elements of the Array from index// l to index rfunction range_gcd(seg_tree, v, tl, tr, l, r) {  // Base Case  if (l > r) return 0;  if (l == tl && r == tr) return seg_tree[v];   // Find the middle range  let tm = Math.floor((tl + tr) / 2);   // Find the GCD and return  return __gcd(    range_gcd(seg_tree, 2 * v, tl, tm, l, Math.min(tm, r)),     range_gcd(seg_tree, 2 * v + 1, tm + 1, tr, Math.max(tm + 1, l), r)  );} // Function to print maximum length of// the subarray having GCD > onefunction maxSubarrayLen(arr, n) {  // Stores the Segment Tree  let seg_tree = new Array(4 * n + 1).fill(0);   // Function call to build the  // Segment tree from array arr[]  build_tree(arr, seg_tree, 0, n - 1, 1);   // Store maximum length of subarray  let maxLen = 0;   // Starting and ending pointer of  // the current window  let l = 0,    r = 0;   while (r < n && l < n) {    // Case where the GCD of the    // current window is 1    if (range_gcd(seg_tree, 1, 0, n - 1, l, r) == 1) {      l++;    }     // Update the maximum length    maxLen = Math.max(maxLen, r - l + 1);    r++;  }   // Print answer  document.write(maxLen);} // Driver Code let arr = [410, 52, 51, 180, 222, 33, 33];let N = arr.length;maxSubarrayLen(arr, N); // This code is contributed by gfgking.</script>
  
5
 
 
Time Complexity: O(N*log N)Auxiliary Space: O(N)
 
avijitmondal1998
_saurabh_jaiswal
gfgking
lokeshpotta20
shikhasingrajput
divyesh072019
HCF
Segment-Tree
sliding-window
subarray
Advanced Data Structure
Arrays
Mathematical
Recursion
Tree
sliding-window
Arrays
Mathematical
Recursion
Tree
Segment-Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Ordered Set and GNU C++ PBDS
2-3 Trees | (Search, Insert and Deletion)
Extendible Hashing (Dynamic approach to DBMS)
Suffix Array | Set 1 (Introduction)
Interval Tree
Arrays in Java
Arrays in C/C++
Maximum and minimum of an array using minimum number of comparisons
Write a program to reverse an array or string
Program for array rotation