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: 2 Explanation: 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++
#include <bits/stdc++.h>
using namespace std;
void maxSubarrayLen( int arr[], int n)
{
int maxLen = 0;
for ( int i = 0; i < n; i++) {
int gcd = 0;
for ( int j = i; j < n; j++) {
gcd = __gcd(gcd, arr[j]);
if (gcd > 1)
maxLen = max(maxLen, j - i + 1);
else
break ;
}
}
cout << maxLen;
}
int main()
{
int arr[] = { 410, 52, 51, 180,
222, 33, 33 };
int N = sizeof (arr) / sizeof ( int );
maxSubarrayLen(arr, N);
return 0;
}
|
Java
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 void maxSubarrayLen( int arr[], int n)
{
int maxLen = 0 ;
for ( int i = 0 ; i < n; i++) {
int gcd = 0 ;
for ( int j = i; j < n; j++) {
gcd = __gcd(gcd, arr[j]);
if (gcd > 1 )
maxLen = Math.max(maxLen, j - i + 1 );
else
break ;
}
}
System.out.print(maxLen);
}
public static void main(String[] args)
{
int arr[] = { 410 , 52 , 51 , 180 ,
222 , 33 , 33 };
int N = arr.length;
maxSubarrayLen(arr, N);
}
}
|
Python3
def __gcd(a, b):
if (b = = 0 ): return a;
return __gcd(b, a % b);
def maxSubarrayLen(arr, n) :
maxLen = 0 ;
for i in range (n):
gcd = 0 ;
for j in range (i, n):
gcd = __gcd(gcd, arr[j]);
if (gcd > 1 ):
maxLen = max (maxLen, j - i + 1 );
else : break ;
print (maxLen);
arr = [ 410 , 52 , 51 , 180 , 222 , 33 , 33 ];
N = len (arr)
maxSubarrayLen(arr, N);
|
C#
using System;
using System.Collections.Generic;
public 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 void maxSubarrayLen( int []arr, int n)
{
int maxLen = 0;
for ( int i = 0; i < n; i++) {
int gcd = 0;
for ( int j = i; j < n; j++) {
gcd = __gcd(gcd, arr[j]);
if (gcd > 1)
maxLen = Math.Max(maxLen, j - i + 1);
else
break ;
}
}
Console.Write(maxLen);
}
static public void Main (){
int []arr = { 410, 52, 51, 180,
222, 33, 33 };
int N = arr.Length;
maxSubarrayLen(arr, N);
}
}
|
Javascript
<script>
function __gcd(a, b) {
if (b == 0) return a;
return __gcd(b, a % b);
}
function maxSubarrayLen(arr, n)
{
let maxLen = 0;
for (let i = 0; i < n; i++)
{
let gcd = 0;
for (let j = i; j < n; j++)
{
gcd = __gcd(gcd, arr[j]);
if (gcd > 1) maxLen = Math.max(maxLen, j - i + 1);
else break ;
}
}
document.write(maxLen);
}
let arr = [410, 52, 51, 180, 222, 33, 33];
let N = arr.length;
maxSubarrayLen(arr, N);
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
void build_tree( int * b, vector< int >& seg_tree,
int l, int r, int vertex)
{
if (l == r) {
seg_tree[vertex] = b[l];
return ;
}
int mid = (l + r) / 2;
build_tree(b, seg_tree, l, mid,
2 * vertex);
build_tree(b, seg_tree, mid + 1,
r, 2 * vertex + 1);
seg_tree[vertex] = __gcd(seg_tree[2 * vertex],
seg_tree[2 * vertex + 1]);
}
int range_gcd(vector< int >& seg_tree, int v,
int tl, int tr,
int l, int r)
{
if (l > r)
return 0;
if (l == tl && r == tr)
return seg_tree[v];
int tm = (tl + tr) / 2;
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));
}
void maxSubarrayLen( int arr[], int n)
{
vector< int > seg_tree(4 * (n) + 1, 0);
build_tree(arr, seg_tree, 0, n - 1, 1);
int maxLen = 0;
int l = 0, r = 0;
while (r < n && l < n) {
if (range_gcd(seg_tree, 1, 0,
n - 1, l, r)
== 1) {
l++;
}
maxLen = max(maxLen, r - l + 1);
r++;
}
cout << maxLen;
}
int main()
{
int arr[] = { 410, 52, 51, 180, 222, 33, 33 };
int N = sizeof (arr) / sizeof ( int );
maxSubarrayLen(arr, N);
return 0;
}
|
Java
class GFG{
static void build_tree( int [] b, int [] seg_tree,
int l, int r, int vertex)
{
if (l == r) {
seg_tree[vertex] = b[l];
return ;
}
int mid = (l + r) / 2 ;
build_tree(b, seg_tree, l, mid,
2 * vertex);
build_tree(b, seg_tree, mid + 1 ,
r, 2 * vertex + 1 );
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);
}
static int range_gcd( int [] seg_tree, int v,
int tl, int tr,
int l, int r)
{
if (l > r)
return 0 ;
if (l == tl && r == tr)
return seg_tree[v];
int tm = (tl + tr) / 2 ;
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));
}
static void maxSubarrayLen( int arr[], int n)
{
int []seg_tree = new int [ 4 * (n) + 1 ];
build_tree(arr, seg_tree, 0 , n - 1 , 1 );
int maxLen = 0 ;
int l = 0 , r = 0 ;
while (r < n && l < n) {
if (range_gcd(seg_tree, 1 , 0 ,
n - 1 , l, r)
== 1 ) {
l++;
}
maxLen = Math.max(maxLen, r - l + 1 );
r++;
}
System.out.print(maxLen);
}
public static void main(String[] args)
{
int arr[] = { 410 , 52 , 51 , 180 , 222 , 33 , 33 };
int N = arr.length;
maxSubarrayLen(arr, N);
}
}
|
Python3
def build_tree(b, seg_tree, l, r, vertex):
if (l = = r):
seg_tree[vertex] = b[l]
return
mid = int ((l + r) / 2 )
build_tree(b, seg_tree, l, mid, 2 * vertex)
build_tree(b, seg_tree, mid + 1 , r, 2 * vertex + 1 )
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)
def range_gcd(seg_tree, v, tl, tr, l, r):
if (l > r):
return 0
if (l = = tl and r = = tr):
return seg_tree[v]
tm = int ((tl + tr) / 2 )
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))
def maxSubarrayLen(arr, n):
seg_tree = [ 0 ] * ( 4 * n + 1 )
build_tree(arr, seg_tree, 0 , n - 1 , 1 )
maxLen = 0
l, r = 0 , 0
while (r < n and l < n):
if (range_gcd(seg_tree, 1 , 0 , n - 1 , l, r) = = 1 ):
l + = 1
maxLen = max (maxLen, r - l - 1 )
r + = 1
print (maxLen, end = "")
arr = [ 410 , 52 , 51 , 180 , 222 , 33 , 33 ]
N = len (arr)
maxSubarrayLen(arr, N)
|
C#
using System;
public class GFG
{
static void build_tree( int [] b, int [] seg_tree,
int l, int r, int vertex)
{
if (l == r) {
seg_tree[vertex] = b[l];
return ;
}
int mid = (l + r) / 2;
build_tree(b, seg_tree, l, mid,
2 * vertex);
build_tree(b, seg_tree, mid + 1,
r, 2 * vertex + 1);
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);
}
static int range_gcd( int [] seg_tree, int v,
int tl, int tr,
int l, int r)
{
if (l > r)
return 0;
if (l == tl && r == tr)
return seg_tree[v];
int tm = (tl + tr) / 2;
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));
}
static void maxSubarrayLen( int []arr, int n)
{
int []seg_tree = new int [4 * (n) + 1];
build_tree(arr, seg_tree, 0, n - 1, 1);
int maxLen = 0;
int l = 0, r = 0;
while (r < n && l < n) {
if (range_gcd(seg_tree, 1, 0,
n - 1, l, r)
== 1) {
l++;
}
maxLen = Math.Max(maxLen, r - l + 1);
r++;
}
Console.Write(maxLen);
}
public static void Main(String[] args)
{
int []arr = { 410, 52, 51, 180, 222, 33, 33 };
int N = arr.Length;
maxSubarrayLen(arr, N);
}
}
|
Javascript
<script>
function __gcd(a, b) {
if (b == 0) return a;
return __gcd(b, a % b);
}
function build_tree(b, seg_tree, l, r, vertex) {
if (l == r) {
seg_tree[vertex] = b[l];
return ;
}
let mid = Math.floor((l + r) / 2);
build_tree(b, seg_tree, l, mid, 2 * vertex);
build_tree(b, seg_tree, mid + 1, r, 2 * vertex + 1);
seg_tree[vertex] = __gcd(seg_tree[2 * vertex], seg_tree[2 * vertex + 1]);
}
function range_gcd(seg_tree, v, tl, tr, l, r) {
if (l > r) return 0;
if (l == tl && r == tr) return seg_tree[v];
let tm = Math.floor((tl + tr) / 2);
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 maxSubarrayLen(arr, n) {
let seg_tree = new Array(4 * n + 1).fill(0);
build_tree(arr, seg_tree, 0, n - 1, 1);
let maxLen = 0;
let l = 0,
r = 0;
while (r < n && l < n) {
if (range_gcd(seg_tree, 1, 0, n - 1, l, r) == 1) {
l++;
}
maxLen = Math.max(maxLen, r - l + 1);
r++;
}
document.write(maxLen);
}
let arr = [410, 52, 51, 180, 222, 33, 33];
let N = arr.length;
maxSubarrayLen(arr, N);
</script>
|
Time Complexity: O(N*log N) Auxiliary Space: O(N)
Related Topic: Subarrays, Subsequences, and Subsets in Array
|