Open In App

Smallest Subarray with given GCD

Last Updated : 22 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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 complexity analysis of below approaches assume that numbers are fixed size and finding GCD of two elements take constant time.
 

Recommended Practice

Find GCD of all subarrays and keep track of the minimum length subarray with gcd k. Time Complexity of this is O(n3), O(n2) for each subarray and O(n) for finding gcd of a subarray.

Method 2

Find GCD of all subarrays using segment tree based approach discussed here. Time complexity of this solution is O(n2logn), O(n2) for each subarray and O(logn) for finding GCD of subarray using segment tree.

Method 3

The idea is to use Segment Tree and Binary Search to achieve time complexity O(n (logn)2).

  1. If we have any number equal to ‘k’ in the array then the answer is 1 as GCD of k is k. Return 1.
  2. If there is no number which is divisible by k, then GCD doesn’t exist. Return -1.
  3. If none of the above cases is true, the length of minimum subarray is either greater than 1 or GCD doesn’t exist. In this case, we follow following steps. 
    • Build segment tree so that we can quickly find GCD of any subarray using the approach discussed here
    • After building Segment Tree, we consider every index as starting point and do binary search for ending point such that the subarray between these two points has GCD k

Following is the implementation of above idea. 

C++




// C++ Program to find GCD of a number in a given Range
// using segment Trees
#include <bits/stdc++.h>
using namespace std;
 
// To store segment tree
int *st;
 
// Function to find gcd of 2 numbers.
int gcd(int a, int b)
{
    if (a < b)
        swap(a, b);
    if (b==0)
        return a;
    return gcd(b, a%b);
}
 
/*  A recursive function to get gcd of given
    range of array indexes. The following are parameters for
    this function.
 
    st    --> Pointer to segment tree
    si --> Index of current node in the segment tree. Initially
               0 is passed as root is always at index 0
    ss & se  --> Starting and ending indexes of the segment
                 represented by current node, i.e., st[index]
    qs & qe  --> Starting and ending indexes of query range */
int findGcd(int ss, int se, int qs, int qe, int si)
{
    if (ss>qe || se < qs)
        return 0;
    if (qs<=ss && qe>=se)
        return st[si];
    int mid = ss+(se-ss)/2;
    return gcd(findGcd(ss, mid, qs, qe, si*2+1),
               findGcd(mid+1, se, qs, qe, si*2+2));
}
 
//Finding The gcd of given Range
int findRangeGcd(int ss, int se, int arr[], int n)
{
    if (ss<0 || se > n-1 || ss>se)
    {
        cout << "Invalid Arguments" << "\n";
        return -1;
    }
    return findGcd(0, n-1, ss, se, 0);
}
 
// A recursive function that constructs Segment Tree for
// array[ss..se]. si is index of current node in segment
// tree st
int constructST(int arr[], int ss, int se, int si)
{
    if (ss==se)
    {
        st[si] = arr[ss];
        return st[si];
    }
    int mid = ss+(se-ss)/2;
    st[si] = gcd(constructST(arr, ss, mid, si*2+1),
                 constructST(arr, mid+1, se, si*2+2));
    return st[si];
}
 
/* Function to construct segment tree from given array.
   This function allocates memory for segment tree and
   calls constructSTUtil() to fill the allocated memory */
int *constructSegmentTree(int arr[], int n)
{
    int height = (int)(ceil(log2(n)));
    int size = 2*(int)pow(2, height)-1;
    st = new int[size];
    constructST(arr, 0, n-1, 0);
    return st;
}
 
// Returns size of smallest subarray of arr[0..n-1]
// with GCD equal to k.
int findSmallestSubarr(int arr[], int n, int k)
{
    // To check if a multiple of k exists.
    bool found = false;
 
    // Find if k or its multiple is present
    for (int i=0; i<n; i++)
    {
        // If k is present, then subarray size is 1.
        if (arr[i] == k)
            return 1;
 
        // Break the loop to indicate presence of a
        // multiple of k.
        if (arr[i] % k == 0)
            found = true;
    }
 
    // If there was no multiple of k in arr[], then
    // we can't get k as GCD.
    if (found == false)
        return -1;
 
    // If there is a multiple of k in arr[], build
    // segment tree from given array
    constructSegmentTree(arr, n);
 
    // Initialize result
    int res = n+1;
 
    // Now consider every element as starting point
    // and search for ending point using Binary Search
    for (int i=0; i<n-1; i++)
    {
        // a[i] cannot be a starting point, if it is
        // not a multiple of k.
        if (arr[i] % k != 0)
            continue;
 
        // Initialize indexes for binary search of closest
        // ending point to i with GCD of subarray as k.
        int low = i+1;
        int high = n-1;
 
        // Initialize closest ending point for i.
        int closest = 0;
 
        // Binary Search for closest ending point
        // with GCD equal to k.
        while (true)
        {
            // Find middle point and GCD of subarray
            // arr[i..mid]
            int mid = low + (high-low)/2;
            int gcd = findRangeGcd(i, mid, arr, n);
 
            // If GCD is more than k, look further
            if (gcd > k)
                low = mid;
 
            // If GCD is k, store this point and look for
            // a closer point
            else if (gcd == k)
            {
                high = mid;
                closest = mid;
            }
 
            // If GCD is less than, look closer
            else
                high = mid;
 
            // If termination condition reached, set
            // closest
            if (abs(high-low) <= 1)
            {
                if (findRangeGcd(i, low, arr, n) == k)
                    closest = low;
                else if (findRangeGcd(i, high, arr, n)==k)
                    closest = high;
                break;
            }
        }
 
        if (closest != 0)
            res = min(res, closest - i + 1);
    }
 
    // If res was not changed by loop, return -1,
    // else return its value.
    return (res == n+1) ? -1 : res;
}
 
// Driver program to test above functions
int main()
{
    int n = 8;
    int k = 3;
    int arr[] = {6, 9, 7, 10, 12, 24, 36, 27};
    cout << "Size of smallest sub-array with given"
         << " size is " << findSmallestSubarr(arr, n, k);
    return 0;
}


Java




// Java Program to find GCD of a number in a given Range
// using segment Trees
class GFG
{
 
// To store segment tree
static int []st;
 
// Function to find gcd of 2 numbers.
static int gcd(int a, int b)
{
    if (a < b)
        swap(a, b);
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
 
private static void swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}
/* A recursive function to get gcd of given
    range of array indexes. The following are parameters for
    this function.
 
    st --> Pointer to segment tree
    si --> Index of current node in the segment tree. Initially
            0 is passed as root is always at index 0
    ss & se --> Starting and ending indexes of the segment
                represented by current node, i.e., st[index]
    qs & qe --> Starting and ending indexes of query range */
static int findGcd(int ss, int se, int qs, int qe, int si)
{
    if (ss > qe || se < qs)
        return 0;
    if (qs <= ss && qe >= se)
        return st[si];
    int mid = ss + (se - ss) / 2;
    return gcd(findGcd(ss, mid, qs, qe, si * 2 + 1),
            findGcd(mid + 1, se, qs, qe, si * 2 + 2));
}
 
// Finding The gcd of given Range
static int findRangeGcd(int ss, int se, int arr[], int n)
{
    if (ss < 0 || se > n-1 || ss > se)
    {
        System.out.println("Invalid Arguments");
        return -1;
    }
    return findGcd(0, n - 1, ss, se, 0);
}
 
// A recursive function that constructs Segment Tree for
// array[ss..se]. si is index of current node in segment
// tree st
static int constructST(int arr[], int ss, int se, int si)
{
    if (ss == se)
    {
        st[si] = arr[ss];
        return st[si];
    }
    int mid = ss + (se - ss) / 2;
    st[si] = gcd(constructST(arr, ss, mid, si * 2 + 1),
                constructST(arr, mid+1, se, si * 2 + 2));
    return st[si];
}
 
/* Function to construct segment tree from given array.
This function allocates memory for segment tree and
calls constructSTUtil() to fill the allocated memory */
static int []constructSegmentTree(int arr[], int n)
{
    int height = (int)(Math.ceil(Math.log(n)));
    int size = 2*(int)Math.pow(2, height) - 1;
    st = new int[size];
    constructST(arr, 0, n - 1, 0);
    return st;
}
 
// Returns size of smallest subarray of arr[0..n-1]
// with GCD equal to k.
static int findSmallestSubarr(int arr[], int n, int k)
{
    // To check if a multiple of k exists.
    boolean found = false;
 
    // Find if k or its multiple is present
    for (int i = 0; i < n; i++)
    {
        // If k is present, then subarray size is 1.
        if (arr[i] == k)
            return 1;
 
        // Break the loop to indicate presence of a
        // multiple of k.
        if (arr[i] % k == 0)
            found = true;
    }
 
    // If there was no multiple of k in arr[], then
    // we can't get k as GCD.
    if (found == false)
        return -1;
 
    // If there is a multiple of k in arr[], build
    // segment tree from given array
    constructSegmentTree(arr, n);
 
    // Initialize result
    int res = n + 1;
 
    // Now consider every element as starting point
    // and search for ending point using Binary Search
    for (int i = 0; i < n - 1; i++)
    {
        // a[i] cannot be a starting point, if it is
        // not a multiple of k.
        if (arr[i] % k != 0)
            continue;
 
        // Initialize indexes for binary search of closest
        // ending point to i with GCD of subarray as k.
        int low = i + 1;
        int high = n - 1;
 
        // Initialize closest ending point for i.
        int closest = 0;
 
        // Binary Search for closest ending point
        // with GCD equal to k.
        while (true)
        {
            // Find middle point and GCD of subarray
            // arr[i..mid]
            int mid = low + (high-low)/2;
            int gcd = findRangeGcd(i, mid, arr, n);
 
            // If GCD is more than k, look further
            if (gcd > k)
                low = mid;
 
            // If GCD is k, store this point and look for
            // a closer point
            else if (gcd == k)
            {
                high = mid;
                closest = mid;
            }
 
            // If GCD is less than, look closer
            else
                high = mid;
 
            // If termination condition reached, set
            // closest
            if (Math.abs(high-low) <= 1)
            {
                if (findRangeGcd(i, low, arr, n) == k)
                    closest = low;
                else if (findRangeGcd(i, high, arr, n)==k)
                    closest = high;
                break;
            }
        }
 
        if (closest != 0)
            res = Math.min(res, closest - i + 1);
    }
 
    // If res was not changed by loop, return -1,
    // else return its value.
    return (res == n+1) ? -1 : res;
}
 
// Driver code
public static void main(String args[])
{
    int n = 8;
    int k = 3;
    int arr[] = {6, 9, 7, 10, 12, 24, 36, 27};
    System.out.println("Size of smallest sub-array with given"
        + " size is " + findSmallestSubarr(arr, n, k));
}
}
 
// This code is contributed by Rajput-Ji


Python3




# Python Program to find GCD of a number in a given Range
# using segment Trees
 
# To store segment tree
st = []
 
# Function to find gcd of 2 numbers.
def gcd(a: int, b: int) -> int:
    if a < b:
        a, b = b, a
    if b == 0:
        return a
    return gcd(b, a % b)
 
# A recursive function to get gcd of given
# range of array indexes. The following are parameters for
# this function.
 
# st --> Pointer to segment tree
# si --> Index of current node in the segment tree. Initially
#             0 is passed as root is always at index 0
# ss & se --> Starting and ending indexes of the segment
#                 represented by current node, i.e., st[index]
# qs & qe --> Starting and ending indexes of query range
def findGcd(ss: int, se: int, qs: int, qe: int, si: int) -> int:
    if ss > qe or se < qs:
        return 0
    if qs <= ss and qe >= se:
        return st[si]
    mid = ss + (se - ss) // 2
    return gcd(findGcd(ss, mid, qs, qe, si * 2 + 1),
            findGcd(mid + 1, se, qs, qe, si * 2 + 2))
 
# Finding The gcd of given Range
def findRangeGcd(ss: int, se: int, arr: list, n: int) -> int:
    if ss < 0 or se > n - 1 or ss > se:
        print("invalid Arguments")
        return -1
    return findGcd(0, n - 1, ss, se, 0)
 
# A recursive function that constructs Segment Tree for
# array[ss..se]. si is index of current node in segment
# tree st
def constructST(arr: list, ss: int, se: int, si: int) -> int:
    if ss == se:
        st[si] = arr[ss]
        return st[si]
    mid = ss + (se - ss) // 2
    st[si] = gcd(constructST(arr, ss, mid, si * 2 + 1),
                constructST(arr, mid + 1, se, si * 2 + 2))
    return st[si]
 
# Function to construct segment tree from given array.
# This function allocates memory for segment tree and
# calls constructSTUtil() to fill the allocated memory
def constructSegmentTree(arr: list, n: int) -> list:
    global st
    from math import ceil, log2, pow
 
    height = int(ceil(log2(n)))
    size = 2 * int(pow(2, height)) - 1
    st = [0] * size
    constructST(arr, 0, n - 1, 0)
    return st
 
# Returns size of smallest subarray of arr[0..n-1]
# with GCD equal to k.
def findSmallestSubarr(arr: list, n: int, k: int) -> int:
 
    # To check if a multiple of k exists.
    found = False
 
    # Find if k or its multiple is present
    for i in range(n):
 
        # If k is present, then subarray size is 1.
        if arr[i] == k:
            return 1
 
        # Break the loop to indicate presence of a
        # multiple of k.
        if arr[i] % k == 0:
            found = True
 
    # If there was no multiple of k in arr[], then
    # we can't get k as GCD.
    if found == False:
        return -1
 
    # If there is a multiple of k in arr[], build
    # segment tree from given array
    constructSegmentTree(arr, n)
 
    # Initialize result
    res = n + 1
 
    # Now consider every element as starting point
    # and search for ending point using Binary Search
    for i in range(n - 1):
 
        # a[i] cannot be a starting point, if it is
        # not a multiple of k.
        if arr[i] % k != 0:
            continue
 
        # Initialize indexes for binary search of closest
        # ending point to i with GCD of subarray as k.
        low = i + 1
        high = n - 1
 
        # Initialize closest ending point for i.
        closest = 0
 
        # Binary Search for closest ending point
        # with GCD equal to k.
        while True:
 
            # Find middle point and GCD of subarray
            # arr[i..mid]
            mid = low + (high - low) // 2
            gcd = findRangeGcd(i, mid, arr, n)
 
            # If GCD is more than k, look further
            if gcd > k:
                low = mid
 
            # If GCD is k, store this point and look for
            # a closer point
            else if gcd == k:
                high = mid
                closest = mid
 
            # If GCD is less than, look closer
            else:
                high = mid
 
            # If termination condition reached, set
            # closest
            if abs(high - low) <= 1:
                if findRangeGcd(i, low, arr, n) == k:
                    closest = low
                else if findRangeGcd(i, high, arr, n) == k:
                    closest = high
                break
        if closest != 0:
            res = min(res, closest - i + 1)
 
    # If res was not changed by loop, return -1,
    # else return its value.
    return -1 if res == n + 1 else res
 
# Driver Code
if __name__ == "__main__":
    n = 8
    k = 3
    arr = [6, 9, 7, 10, 12, 24, 36, 27]
    print("Size of smallest sub-array with given size is",
        findSmallestSubarr(arr, n, k))
 
# This code is contributed by
# sanjeev2552


C#




// C# Program to find GCD of a number in a given Range
// using segment Trees
using System;
 
class GFG
{
 
// To store segment tree
static int []st;
 
// Function to find gcd of 2 numbers.
static int gcd(int a, int b)
{
    if (a < b)
        swap(a, b);
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
 
private static void swap(int x, int y)
{
    int temp = x;
    x = y;
    y = temp;
}
 
/* A recursive function to get gcd of given
    range of array indexes. The following are parameters for
    this function.
 
    st --> Pointer to segment tree
    si --> Index of current node in the segment tree. Initially
            0 is passed as root is always at index 0
    ss & se --> Starting and ending indexes of the segment
                represented by current node, i.e., st[index]
    qs & qe --> Starting and ending indexes of query range */
static int findGcd(int ss, int se, int qs, int qe, int si)
{
    if (ss > qe || se < qs)
        return 0;
    if (qs <= ss && qe >= se)
        return st[si];
    int mid = ss + (se - ss) / 2;
    return gcd(findGcd(ss, mid, qs, qe, si * 2 + 1),
            findGcd(mid + 1, se, qs, qe, si * 2 + 2));
}
 
// Finding The gcd of given Range
static int findRangeGcd(int ss, int se, int []arr, int n)
{
    if (ss < 0 || se > n-1 || ss > se)
    {
        Console.WriteLine("Invalid Arguments");
        return -1;
    }
    return findGcd(0, n - 1, ss, se, 0);
}
 
// A recursive function that constructs Segment Tree for
// array[ss..se]. si is index of current node in segment
// tree st
static int constructST(int []arr, int ss, int se, int si)
{
    if (ss == se)
    {
        st[si] = arr[ss];
        return st[si];
    }
    int mid = ss + (se - ss) / 2;
    st[si] = gcd(constructST(arr, ss, mid, si * 2 + 1),
                constructST(arr, mid+1, se, si * 2 + 2));
    return st[si];
}
 
/* Function to construct segment tree from given array.
This function allocates memory for segment tree and
calls constructSTUtil() to fill the allocated memory */
static int []constructSegmentTree(int []arr, int n)
{
    int height = (int)(Math.Ceiling(Math.Log(n)));
    int size = 2*(int)Math.Pow(2, height) - 1;
    st = new int[size];
    constructST(arr, 0, n - 1, 0);
    return st;
}
 
// Returns size of smallest subarray of arr[0..n-1]
// with GCD equal to k.
static int findSmallestSubarr(int []arr, int n, int k)
{
    // To check if a multiple of k exists.
    bool found = false;
 
    // Find if k or its multiple is present
    for (int i = 0; i < n; i++)
    {
        // If k is present, then subarray size is 1.
        if (arr[i] == k)
            return 1;
 
        // Break the loop to indicate presence of a
        // multiple of k.
        if (arr[i] % k == 0)
            found = true;
    }
 
    // If there was no multiple of k in arr[], then
    // we can't get k as GCD.
    if (found == false)
        return -1;
 
    // If there is a multiple of k in arr[], build
    // segment tree from given array
    constructSegmentTree(arr, n);
 
    // Initialize result
    int res = n + 1;
 
    // Now consider every element as starting point
    // and search for ending point using Binary Search
    for (int i = 0; i < n - 1; i++)
    {
        // a[i] cannot be a starting point, if it is
        // not a multiple of k.
        if (arr[i] % k != 0)
            continue;
 
        // Initialize indexes for binary search of closest
        // ending point to i with GCD of subarray as k.
        int low = i + 1;
        int high = n - 1;
 
        // Initialize closest ending point for i.
        int closest = 0;
 
        // Binary Search for closest ending point
        // with GCD equal to k.
        while (true)
        {
            // Find middle point and GCD of subarray
            // arr[i..mid]
            int mid = low + (high-low)/2;
            int gcd = findRangeGcd(i, mid, arr, n);
 
            // If GCD is more than k, look further
            if (gcd > k)
                low = mid;
 
            // If GCD is k, store this point and look for
            // a closer point
            else if (gcd == k)
            {
                high = mid;
                closest = mid;
            }
 
            // If GCD is less than, look closer
            else
                high = mid;
 
            // If termination condition reached, set
            // closest
            if (Math.Abs(high-low) <= 1)
            {
                if (findRangeGcd(i, low, arr, n) == k)
                    closest = low;
                else if (findRangeGcd(i, high, arr, n)==k)
                    closest = high;
                break;
            }
        }
 
        if (closest != 0)
            res = Math.Min(res, closest - i + 1);
    }
 
    // If res was not changed by loop, return -1,
    // else return its value.
    return (res == n+1) ? -1 : res;
}
 
// Driver code
public static void Main(String []args)
{
    int n = 8;
    int k = 3;
    int []arr = {6, 9, 7, 10, 12, 24, 36, 27};
    Console.WriteLine("Size of smallest sub-array with given"
        + " size is " + findSmallestSubarr(arr, n, k));
}
}
 
/* This code is contributed by PrinciRaj1992 */


Javascript




<script>
  
// Javascript Program to find GCD of a number in a given Range
// using segment Trees
 
// To store segment tree
var st = [];
 
// Function to find gcd of 2 numbers.
function gcd(a,  b)
{
    if (a < b)
        [a, b] = [b,a];
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
 
 
/* A recursive function to get gcd of given
    range of array indexes. The following are parameters for
    this function.
 
    st --> Pointer to segment tree
    si --> Index of current node in the segment tree. Initially
            0 is passed as root is always at index 0
    ss & se --> Starting and ending indexes of the segment
                represented by current node, i.e., st[index]
    qs & qe --> Starting and ending indexes of query range */
function findGcd(ss, se, qs, qe, si)
{
    if (ss > qe || se < qs)
        return 0;
    if (qs <= ss && qe >= se)
        return st[si];
    var mid = ss + parseInt((se - ss) / 2);
    return gcd(findGcd(ss, mid, qs, qe, si * 2 + 1),
            findGcd(mid + 1, se, qs, qe, si * 2 + 2));
}
 
// Finding The gcd of given Range
function findRangeGcd(ss, se, arr, n)
{
    if (ss < 0 || se > n-1 || ss > se)
    {
        document.write("Invalid Arguments");
        return -1;
    }
    return findGcd(0, n - 1, ss, se, 0);
}
 
// A recursive function that constructs Segment Tree for
// array[ss..se]. si is index of current node in segment
// tree st
function constructST(arr, ss, se, si)
{
    if (ss == se)
    {
        st[si] = arr[ss];
        return st[si];
    }
    var mid = ss + parseInt((se - ss) / 2);
    st[si] = gcd(constructST(arr, ss, mid, si * 2 + 1),
                constructST(arr, mid+1, se, si * 2 + 2));
    return st[si];
}
 
/* Function to construct segment tree from given array.
This function allocates memory for segment tree and
calls constructSTUtil() to fill the allocated memory */
function constructSegmentTree(arr, n)
{
    var height = parseInt(Math.ceil(Math.log(n)));
    var size = 2*parseInt(Math.pow(2, height)) - 1;
    st = Array(size).fill(0);
    constructST(arr, 0, n - 1, 0);
    return st;
}
 
// Returns size of smallest subarray of arr[0..n-1]
// with GCD equal to k.
function findSmallestSubarr(arr, n, k)
{
    // To check if a multiple of k exists.
    var found = false;
 
    // Find if k or its multiple is present
    for (var i = 0; i < n; i++)
    {
        // If k is present, then subarray size is 1.
        if (arr[i] == k)
            return 1;
 
        // Break the loop to indicate presence of a
        // multiple of k.
        if (arr[i] % k == 0)
            found = true;
    }
 
    // If there was no multiple of k in arr[], then
    // we can't get k as GCD.
    if (found == false)
        return -1;
 
    // If there is a multiple of k in arr[], build
    // segment tree from given array
    constructSegmentTree(arr, n);
 
    // Initialize result
    var res = n + 1;
 
    // Now consider every element as starting point
    // and search for ending point using Binary Search
    for (var i = 0; i < n - 1; i++)
    {
        // a[i] cannot be a starting point, if it is
        // not a multiple of k.
        if (arr[i] % k != 0)
            continue;
 
        // Initialize indexes for binary search of closest
        // ending point to i with GCD of subarray as k.
        var low = i + 1;
        var high = n - 1;
 
        // Initialize closest ending point for i.
        var closest = 0;
 
        // Binary Search for closest ending point
        // with GCD equal to k.
        while (true)
        {
            // Find middle point and GCD of subarray
            // arr[i..mid]
            var mid = low + parseInt((high-low)/2);
            var gcd = findRangeGcd(i, mid, arr, n);
 
            // If GCD is more than k, look further
            if (gcd > k)
                low = mid;
 
            // If GCD is k, store this point and look for
            // a closer point
            else if (gcd == k)
            {
                high = mid;
                closest = mid;
            }
 
            // If GCD is less than, look closer
            else
                high = mid;
 
            // If termination condition reached, set
            // closest
            if (Math.abs(high-low) <= 1)
            {
                if (findRangeGcd(i, low, arr, n) == k)
                    closest = low;
                else if (findRangeGcd(i, high, arr, n)==k)
                    closest = high;
                break;
            }
        }
 
        if (closest != 0)
            res = Math.min(res, closest - i + 1);
    }
 
    // If res was not changed by loop, return -1,
    // else return its value.
    return (res == n+1) ? -1 : res;
}
 
// Driver code
var n = 8;
var k = 3;
var arr = [6, 9, 7, 10, 12, 24, 36, 27];
document.write("Size of smallest sub-array with given"
    + " size is " + findSmallestSubarr(arr, n, k));
 
// This code is contributed by itsok.
</script>


Output

Size of smallest sub-array with given size is 2

Example: 

arr[] = {6, 9, 7, 10, 12, 24, 36, 27}, K = 3

// Initial value of minLen is equal to size 
// of array
minLen = 8 

No element is equal to k so result is either 
greater than 1 or doesn't exist. 

First index

  • GCD of subarray from 1 to 5 is 1.
  • GCD < k
  • GCD of subarray from 1 to 3 is 1.
  • GCD < k
  • GCD of subarray from 1 to 2 is 3
  • minLen = minimum(8, 2) = 2

Second Index 

  • GCD of subarray from 2 to 5 is 1
  • GCD < k
  • GCD of subarray from 2 to 4 is 1
  • GCD < k
  • GCD of subarray from 6 to 8 is 3
  • minLen = minimum(2, 3) = 2.
     

.

 

.

 

.

 

Sixth Index

 

  • GCD of subarray from 6 to 7 is 12
  • GCD > k
  • GCD of subarray from 6 to 8 is 3
  • minLen = minimum(2, 3) = 2

Time Complexity: O(n (logn)2), O(n) for traversing to each index, O(logn) for each subarray and O(logn) for GCD of each subarray.

Space Complexity :  O(1)



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

Similar Reads