Subarreglo más pequeño con GCD dado

Dada una array arr[] de n números y un entero k, encuentre la longitud de la sub-array mínima con gcd igual a k.
Ejemplo: 

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 

Nota: El análisis de la complejidad del tiempo de los enfoques siguientes supone que los números tienen un tamaño fijo y encontrar el GCD de dos elementos lleva un tiempo constante.
 

Encuentre GCD de todos los subarreglos y realice un seguimiento del subarreglo de longitud mínima con gcd k. La complejidad temporal de esto es O(n 3 ), O(n 2 ) para cada subarreglo y O(n) para encontrar gcd de un subarreglo.

Método 2

Encuentre el GCD de todos los subarreglos usando el enfoque basado en el árbol de segmentos discutido aquí . La complejidad temporal de esta solución es O(n 2 logn), O(n 2 ) para cada subarreglo y O(logn) para encontrar el GCD del subarreglo usando un árbol de segmentos.

Método 3

La idea es utilizar el árbol de segmentos y la búsqueda binaria para lograr la complejidad de tiempo O(n (logn) 2 ).

  1. Si tenemos cualquier número igual a ‘k’ en la array, la respuesta es 1, ya que MCD de k es k. Regreso 1.
  2. Si no hay ningún número que sea divisible por k, entonces MCD no existe. Devuelve -1.
  3. Si ninguno de los casos anteriores es cierto, la longitud del subarreglo mínimo es mayor que 1 o GCD no existe. En este caso, seguimos los siguientes pasos. 
    • Cree un árbol de segmentos para que podamos encontrar rápidamente GCD de cualquier subarreglo utilizando el enfoque discutido aquí
    • Después de construir el árbol de segmentos, consideramos cada índice como punto de partida y hacemos una búsqueda binaria para el punto final de modo que el subarreglo entre estos dos puntos tenga GCD k

A continuación se muestra la implementación de la idea anterior. 

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>
Producción

Size of smallest sub-array with given size is 2

Ejemplo: 

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. 

primer índice

  • MCD del subarreglo de 1 a 5 es 1.
  • MCD < k
  • MCD del subarreglo de 1 a 3 es 1.
  • MCD < k
  • GCD del subarreglo de 1 a 2 es 3
  • minLen = mínimo (8, 2) = 2

Segundo Índice 

  • MCD del subarreglo de 2 a 5 es 1
  • MCD < k
  • MCD del subarreglo de 2 a 4 es 1
  • MCD < k
  • MCD del subarreglo de 6 a 8 es 3
  • minLen = mínimo (2, 3) = 2.
     

.

.

.

Sexto Índice

  • MCD del subarreglo de 6 a 7 es 12
  • MCD > k
  • MCD del subarreglo de 6 a 8 es 3
  • minLen = mínimo (2, 3) = 2

Complejidad de tiempo: O(n (logn) 2 ) , O(n) para atravesar cada índice, O(logn) para cada subarreglo y O(logn) para GCD de cada subarreglo.

Este artículo es una contribución de Nikhil Tekwani. Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *