Longest subarray with GCD greater than 1
Last Updated :
22 Aug, 2022
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++
// C++ program of the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to find maximum length of
// the subarray having GCD > one
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 = max(maxLen, j - i + 1);
else
break;
}
}
// Print maximum length
cout << maxLen;
}
// Driver Code
int main()
{
int arr[] = { 410, 52, 51, 180,
222, 33, 33 };
int N = sizeof(arr) / sizeof(int);
maxSubarrayLen(arr, N);
return 0;
}
Java
// Java code for above approach
import 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 > one
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
System.out.print(maxLen);
}
// Driver Code
public 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.
Python3
# Python program of the above approach
def __gcd(a, b):
if (b == 0): return a;
return __gcd(b, a % b);
# Function to find maximum length of
# the subarray having GCD > one
def 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 Code
arr = [410, 52, 51, 180, 222, 33, 33];
N = len(arr)
maxSubarrayLen(arr, N);
# This code is contributed by gfgking.
C#
// C# code for the above approach
using 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
JavaScript
<script>
// Javascript program of the above approach
function __gcd(a, b) {
if (b == 0) return a;
return __gcd(b, a % b);
}
// Function to find maximum length of
// the subarray having GCD > one
function 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 Code
let arr = [410, 52, 51, 180, 222, 33, 33];
let N = arr.length;
maxSubarrayLen(arr, N);
// This code is contributed by _saurabh_jaiswal.
</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++
// 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) time
void 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 r
int 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 > one
void 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 Code
int main()
{
int arr[] = { 410, 52, 51, 180, 222, 33, 33 };
int N = sizeof(arr) / sizeof(int);
maxSubarrayLen(arr, N);
return 0;
}
Java
// Java program of the above approach
class GFG{
// Function to build the Segment Tree
// from the given array to process
// range queries in log(N) time
static 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 r
static 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 > one
static 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 Code
public 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
# Python3 program of the above approach
# Function to build the Segment Tree
# from the given array to process
# range queries in log(N) time
def 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 r
def 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 > one
def 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#
// C# program of the above approach
using System;
public class GFG
{
// Function to build the Segment Tree
// from the given array to process
// range queries in log(N) time
static 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 r
static 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 > one
static 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 Code
public 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
JavaScript
<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) time
function 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 r
function 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 > one
function 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>
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Related Topic: Subarrays, Subsequences, and Subsets in Array
Similar Reads
Largest subarray with GCD one There is an array with n elements. Find length of the largest subarray having GCD equal to 1. If no subarray with GCD 1, then print -1. Examples : Input : 1 3 5 Output : 3 Input : 2 4 6 Output :-1 Recommended PracticeLargest subarray with GCD oneTry It! A simple solution is to consider every subarra
6 min read
Smallest subarray with GCD as 1 | Segment Tree Given an array arr[], the task is to find the smallest sub-arrays with GCD equal to 1. If there is no such sub-array then print -1. Examples: Input: arr[] = {2, 6, 3} Output: 3 {2, 6, 3} is the only sub-array with GCD = 1. Input: arr[] = {2, 2, 2} Output: -1 Approach: This problem can be solved in O
10 min read
Smallest Subarray with given GCD Given an array arr[] of n numbers and an integer k, find length of the minimum sub-array with gcd equals to k.Example: Input: arr[] = {6, 9, 7, 10, 12, 24, 36, 27}, K = 3 Output: 2 Explanation: GCD of subarray {6,9} is 3. GCD of subarray {24,36,27} is also 3, but {6,9} is the smallest Note: Time com
15+ min read
Largest Subset with GCD 1 Given n integers, we need to find size of the largest subset with GCD equal to 1. Input Constraint : n <= 10^5, A[i] <= 10^5Examples: Input : A = {2, 3, 5}Output : 3Explanation: The largest subset with a GCD greater than 1 is {2, 3, 5}, and the GCD of all the elements in the subset is 3.Input
6 min read
Largest subsequence having GCD greater than 1 Given an array, arr[], find the largest subsequence such that GCD of all those subsequences are greater than 1. Examples: Input: 3, 6, 2, 5, 4 Output: 3 Explanation: There are only three elements(6, 2, 4) having GCD greater than 1 i.e., 2. So the largest subsequence will be 3 Input: 10, 15, 7, 25, 9
14 min read