📜  查找数组中具有最大GCD的对

📅  最后修改于: 2021-05-04 18:36:51             🧑  作者: Mango

我们得到了一个正整数数组。在数组中找到具有最大GCD的线对。
例子:

Input : arr[] : { 1 2 3 4 5 }
Output : 2
Explanation : Pair {2, 4} has GCD 2 which is highest. Other pairs have a GCD of 1.

Input : arr[] : { 2 3 4 8 8 11 12 }
Output : 8
Explanation : Pair {8, 8} has GCD 8 which is highest.

方法1(蛮力) :解决此问题的最简单方法是使用两个循环来生成数组中所有可能的元素对,并同时计算和比较GCD。我们可以使用扩展的欧几里得算法来有效地计算两个数字的GCD。
时间复杂度:O(N ^ 2 * log(max(a,b)))
log(max(a,b))是计算a和b的GCD的时间复杂度。
方法2 :(有效)在此方法中,我们维护一个count数组来存储每个元素的除数的数量。我们将遍历给定的数组,并为每个元素计算其除数,并在count数组的索引处递增。计算除数的过程将花费O(sqrt(arr [i]))时间,其中arr [i]是给定数组在索引i处的元素。整个遍历之后,我们可以简单地将计数数组从最后一个索引遍历到索引1。如果找到的索引值大于1,则意味着它是2个元素的除数,也是最大GCD的除数。
下面是上述方法的实现:

C++
// C++ Code to find pair with
// maximum GCD in an array
#include 
 
using namespace std;
 
// function to find GCD of pair with
// max GCD in the array
int findMaxGCD(int arr[], int n)
{
    // Computing highest element
    int high = 0;
    for (int i = 0; i < n; i++)
        high = max(high, arr[i]);
 
    // Array to store the count of divisors
    // i.e. Potential GCDs
    int divisors[high + 1] = { 0 };
 
    // Iterating over every element
    for (int i = 0; i < n; i++)
    {
        // Calculating all the divisors
        for (int j = 1; j <= sqrt(arr[i]); j++)
        {
            // Divisor found
            if (arr[i] % j == 0)
            {
                // Incrementing count for divisor
                divisors[j]++;
 
                // Element/divisor is also a divisor
                // Checking if both divisors are
                // not same
                if (j != arr[i] / j)
                    divisors[arr[i] / j]++;
            }
        }
    }
 
    // Checking the highest potential GCD
    for (int i = high; i >= 1; i--)
     
        // If this divisor can divide at least 2
        // numbers, it is a GCD of at least 1 pair
        if (divisors[i] > 1)
            return i;   
}
 
// Driver code
int main()
{
    // Array in which pair with max GCD
    // is to be found
    int arr[] = { 1, 2, 4, 8, 8, 12 };
 
    // Size of array
    int n = sizeof(arr) / sizeof(arr[0]);
 
    cout << findMaxGCD(arr,n);
    return 0;
}


Java
// JAVA Code for Find pair with maximum GCD in an array
class GFG {
      
    // function to find GCD of pair with
    // max GCD in the array
    public static int findMaxGCD(int arr[], int n)
    {
        // Computing highest element
        int high = 0;
        for (int i = 0; i < n; i++)
            high = Math.max(high, arr[i]);
      
        // Array to store the count of divisors
        // i.e. Potential GCDs
        int divisors[] =new int[high + 1];
      
        // Iterating over every element
        for (int i = 0; i < n; i++)
        {
            // Calculating all the divisors
            for (int j = 1; j <= Math.sqrt(arr[i]); j++)
            {
                // Divisor found
                if (arr[i] % j == 0)
                {
                    // Incrementing count for divisor
                    divisors[j]++;
      
                    // Element/divisor is also a divisor
                    // Checking if both divisors are
                    // not same
                    if (j != arr[i] / j)
                        divisors[arr[i] / j]++;
                }
            }
        }
      
        // Checking the highest potential GCD
        for (int i = high; i >= 1; i--)
          
            // If this divisor can divide at least 2
            // numbers, it is a GCD of at least 1 pair
            if (divisors[i] > 1)
                return i;
        return 1;
    }
     
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        // Array in which pair with max GCD
        // is to be found
        int arr[] = { 1, 2, 4, 8, 8, 12 };
      
        // Size of array
        int n = arr.length;
      
        System.out.println(findMaxGCD(arr,n));
    }
  }
   
// This code is contributed by Arnav Kr. Mandal.


Python
# Python program to Find pair with
# maximum GCD in an array
import math
 
# function to find GCD of pair with
# max GCD in the array
def findMaxGCD(arr, n) :
     
    # Computing highest element
    high = 0
    i = 0
    while i < n :
        high = max(high, arr[i])
        i = i + 1
  
    # Array to store the count of divisors
    # i.e. Potential GCDs
    divisors = [0] * (high + 1)
  
    # Iterating over every element
    i = 0
    while i < n :
         
        # Calculating all the divisors
        j = 1
        while j <= math.sqrt(arr[i]) :
         
            # Divisor found
            if (arr[i] % j == 0) :
         
                # Incrementing count for divisor
                divisors[j]= divisors[j]+1
                 
                # Element/divisor is also a divisor
                # Checking if both divisors are
                # not same
                if (j != arr[i] / j) :
                    divisors[arr[i] / j] = divisors[arr[i] / j]
                                          + 1
             
            j = j + 1
                     
        i = i + 1           
         
    # Checking the highest potential GCD
    i = high
    while i >= 1 :
         
        # If this divisor can divide at least 2
        # numbers, it is a GCD of at least 1 pair
        if (divisors[i] > 1) :
            return i
        i = i - 1
    return 1
 
# Driver code
 
# Array in which pair with max GCD
# is to be found
arr = [ 1, 2, 4, 8, 8, 12 ]
  
# Size of array
n = len(arr)
 
print findMaxGCD(arr,n)
 
# This code is contributed by Nikita Tiwari.


C#
// C# Code for Find pair with
// maximum GCD in an array
using System;
 
class GFG {
     
    // Function to find GCD of pair
    // with max GCD in the array
    public static int findMaxGCD(int []arr,
                                 int n)
    {
        // Computing highest element
        int high = 0;
        for (int i = 0; i < n; i++)
            high = Math.Max(high, arr[i]);
     
        // Array to store the count of
        // divisors i.e. Potential GCDs
        int []divisors =new int[high + 1];
     
        // Iterating over every element
        for (int i = 0; i < n; i++)
        {
            // Calculating all the divisors
            for (int j = 1; j <=
                 Math.Sqrt(arr[i]); j++)
            {
                // Divisor found
                if (arr[i] % j == 0)
                {
                    // Incrementing count
                    // for divisor
                    divisors[j]++;
     
                    // Element / divisor is also
                    // a divisor Checking if both
                    // divisors are not same
                    if (j != arr[i] / j)
                        divisors[arr[i] / j]++;
                }
            }
        }
     
        // Checking the highest potential GCD
        for (int i = high; i >= 1; i--)
         
            // If this divisor can divide at
            // least 2 numbers, it is a
            // GCD of at least 1 pair
            if (divisors[i] > 1)
                return i;
        return 1;
    }
     
    // Driver Code
    public static void Main(String []args)
    {
        // Array in which pair with
        // max GCD is to be found
        int []arr = {1, 2, 4, 8, 8, 12};
     
        // Size of array
        int n = arr.Length;
     
        Console.WriteLine(findMaxGCD(arr,n));
    }
}
 
// This code is contributed by vt_m.


PHP
= 1; $i--)
     
        // If this divisor can divide
        // at least 2 numbers, it is
        // a GCD of at least 1 pair
        if ($divisors[$i] > 1)
            return $i;
}
 
// Driver code
 
// Array in which pair
// with max GCD is to
// be found
$arr = array( 1, 2, 4, 8, 8, 12 );
 
// Size of array
$n = sizeof($arr);
 
echo findMaxGCD($arr,$n);
 
// This code is contributed by mits
?>


C++
// C++ Code to
// Find pair with
// maximum GCD in
// an array
#include 
using namespace std;
 
// function to find
// GCD of pair with
// max GCD in the
// array
int findMaxGCD(int arr[], int n)
{
    // Calculating MAX in array
    int high = 0;
    for (int i = 0; i < n; i++)
        high = max(high, arr[i]);
 
    // Maintaining count array
    int count[high + 1] = {0};
    for (int i = 0; i < n; i++)
        count[arr[i]]++;
 
    // Variable to store the
    // multiples of a number
    int counter = 0;
 
    // Iterating from MAX to 1
    // GCD is always between
    // MAX and 1. The first
    // GCD found will be the
    // highest as we are
    // decrementing the potential
    // GCD
    for (int i = high; i >= 1; i--)
    {
        int j = i;
       counter = 0;
   
        // Iterating from current
        // potential GCD
        // till it is less than
        // MAX
        while (j <= high)
        {
            // A multiple found
 
            if(count[j] >=2)
               return j;
 
           else if (count[j] == 1)        
                counter++;        
 
            // Incrementing potential
            // GCD by itself
            // To check i, 2i, 3i....
            j += i;
 
            // 2 multiples found,
            // max GCD found
            if (counter == 2)        
                return i;
        }
    }
}
 
// Driver code
int main()
{
    // Array in which pair
    // with max GCD is to
    // be found
    int arr[] = { 1, 2, 4, 8, 8, 12 };
 
    // Size of array
    int n = sizeof(arr) / sizeof(arr[0]);
 
    cout << findMaxGCD(arr, n);
 
    return 0;
}


Java
// Java Code to
// Find pair with
// maximum GCD in
// an array
 
class GFG {
     
    // function to find
    // GCD of pair with
    // max GCD in the
    // array
    public static int findMaxGCD(int arr[], int n)
    {
        // Calculating MAX in
        // array
        int high = 0;
        for (int i = 0; i < n; i++)
            high = Math.max(high, arr[i]);
     
        // Maintaining count array
        int count[]=new int[high + 1];
        for (int i = 0; i < n; i++)
            count[arr[i]]++;
     
        // Variable to store
        // the multiples of
        // a number
        int counter = 0;
     
        // Iterating from MAX
        // to 1 GCD is always
        // between MAX and 1
        // The first GCD found
        // will be the highest
        // as we are decrementing
        // the potential GCD
        for (int i = high; i >= 1; i--)
        {
            int j = i;
     
            // Iterating from current
            // potential GCD till it
            // is less than MAX
            while (j <= high)
            {
                // A multiple found
                if (count[j]>0)    
                    counter+=count[j];        
     
                // Incrementing potential
                // GCD by itself
                // To check i, 2i, 3i....
                j += i;
     
                // 2 multiples found,
                // max GCD found
                if (counter == 2)        
                    return i;
            }
            counter=0;
        }
    return 1;
    }
     
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        // Array in which pair
        // with max GCD is to
        // be found
        int arr[] = {1, 2, 4, 8, 8, 12};
     
        // Size of array
        int n = arr.length;
     
        System.out.println(findMaxGCD(arr,n));
    }
}
 
// This code is contributed by Arnav Kr. Mandal.


Python3
# Python3 Code to
# Find pair with
# maximum GCD in
# an array
 
# function to find
# GCD of pair with
# max GCD in the
# array
def findMaxGCD(arr, n) :
     
    # Calculating MAX in
    # array
    high = 0
    for i in range(0, n) :
        high = max(high, arr[i])
 
    # Maintaining count array
    count = [0] * (high + 1)
    for i in range(0, n) :
        count[arr[i]]+=1
 
    # Variable to store the
    # multiples of a number
    counter = 0
 
    # Iterating from MAX
    # to 1 GCD is always
    # between MAX and 1
    # The first GCD found
    # will be the highest
    # as we are decrementing
    # the potential GCD
    for i in range(high, 0, -1) :
        j = i
 
        # Iterating from current
        # potential GCD till it
        # is less than MAX
        while (j <= high) :
 
            # A multiple found
            if (count[j] >0) :
                counter+=count[j]   
 
            # Incrementing potential
            # GCD by itself
            # To check i, 2i, 3i....
            j += i
 
            # 2 multiples found,
            # max GCD found
            if (counter == 2) :
                return i
        counter=0
         
# Driver code
 
# Array in which pair
# with max GCD is to
# be found
arr = [1, 2, 4, 8, 8, 12]
# Size of array
n = len(arr)
print(findMaxGCD(arr, n))
 
#This code is contributed by Nikita Tiwari.


C#
// C# Code to find pair with
// maximum GCD in an array
using System;
 
class GFG {
     
    // function to find GCD
    // of pair with max
    // max GCD in the array
    public static int findMaxGCD(int []arr,
                                int n)
    {
        // Calculating Max
        // in array
        int high = 0;
        for (int i = 0; i < n; i++)
            high = Math.Max(high, arr[i]);
     
        // Maintaining count array
        int []count=new int[high + 1];
        for (int i = 0; i < n; i++)
            count[arr[i]]++;
     
        // Variable to store
        // the multiples of
        // a number
        int counter = 0;
     
        // Iterating from MAX
        // to 1 GCD is always
        // between MAX and 1
        // The first GCD found
        // will be the highest
        // as we are decrementing
        // the potential GCD
        for (int i = high; i >= 1; i--)
        {
            int j = i;
     
            // Iterating from current
            // potential GCD till it
            // is less than MAX
            while (j <= high)
            {
                // A multiple found
                if (count[j]>0)    
                    counter+=count[j];    
     
                // Incrementing potential
                // GCD by itself
                // To check i, 2i, 3i....
                j += i;
     
                // 2 multiples found,
                // max GCD found
                if (counter == 2)    
                    return i;
            }
            counter=0;
        }
    return 1;
    }
     
    // Driver Code
    public static void Main(String []args)
    {
        // Array in which pair
        // with max GCD is to
        // be found
        int []arr = {1, 2, 4, 8, 8, 12};
     
        // Size of array
        int n = arr.Length;
     
        Console.WriteLine(findMaxGCD(arr,n));
    }
}
 
// This code is contributed by vt_m.


PHP
= 1; $i--)
    {
        $j = $i;
        $counter = 0;
 
        // Iterating from current potential GCD
        // till it is less than MAX
        while ($j <= $high)
        {
            // A multiple found
 
            if($count[$j] >= 2)
            return $j;
 
        else if ($count[$j] == 1)    
                $counter++;    
 
            // Incrementing potential GCD by itself
            // To check i, 2i, 3i....
            $j += $i;
 
            // 2 multiples found, max GCD found
            if ($counter == 2)    
                return $i;
        }
    }
}
 
// Driver code
 
// Array in which pair with max GCD
// is to be found
$arr = array( 1, 2, 4, 8, 8, 12 );
 
// Size of array
$n = count($arr);
 
print(findMaxGCD($arr, $n));
 
// This code is contributed by mits
?>


Javascript


输出:

8

时间复杂度:O(N * sqrt(arr [i])+ H),其中arr [i]表示数组的元素,H表示数组的最大数目。
方法3(最有效) :此方法基于Eratosthenes筛网的想法。
首先让我们解决一个更简单的问题,给定值X,我们必须判断一个对是否GCD等于X。这可以通过检查数组中有多少个元素是X的倍数来完成。大于1,则X将是某对的GCD。
现在,对于具有最大GCD的线对,我们维护原始数组的count数组。我们的方法基于上述问题,采用类似于Sieve的方法进行循环。以下是此方法的分步算法:

  1. 将“ i”从MAX(最大数组元素)迭代为1。
  2. 将“ j”从“ i”迭代到MAX。我们将检查索引’j’处的count数组是否为1。
  3. 每次用“ i”递增索引“ j”。这样,我们可以检查
    i,2i,3i,依此类推。
  4. 如果我们在count数组上两次获得1,这意味着存在i的2倍,这使其成为最高的GCD。

下面是上述方法的实现:

C++

// C++ Code to
// Find pair with
// maximum GCD in
// an array
#include 
using namespace std;
 
// function to find
// GCD of pair with
// max GCD in the
// array
int findMaxGCD(int arr[], int n)
{
    // Calculating MAX in array
    int high = 0;
    for (int i = 0; i < n; i++)
        high = max(high, arr[i]);
 
    // Maintaining count array
    int count[high + 1] = {0};
    for (int i = 0; i < n; i++)
        count[arr[i]]++;
 
    // Variable to store the
    // multiples of a number
    int counter = 0;
 
    // Iterating from MAX to 1
    // GCD is always between
    // MAX and 1. The first
    // GCD found will be the
    // highest as we are
    // decrementing the potential
    // GCD
    for (int i = high; i >= 1; i--)
    {
        int j = i;
       counter = 0;
   
        // Iterating from current
        // potential GCD
        // till it is less than
        // MAX
        while (j <= high)
        {
            // A multiple found
 
            if(count[j] >=2)
               return j;
 
           else if (count[j] == 1)        
                counter++;        
 
            // Incrementing potential
            // GCD by itself
            // To check i, 2i, 3i....
            j += i;
 
            // 2 multiples found,
            // max GCD found
            if (counter == 2)        
                return i;
        }
    }
}
 
// Driver code
int main()
{
    // Array in which pair
    // with max GCD is to
    // be found
    int arr[] = { 1, 2, 4, 8, 8, 12 };
 
    // Size of array
    int n = sizeof(arr) / sizeof(arr[0]);
 
    cout << findMaxGCD(arr, n);
 
    return 0;
}

Java

// Java Code to
// Find pair with
// maximum GCD in
// an array
 
class GFG {
     
    // function to find
    // GCD of pair with
    // max GCD in the
    // array
    public static int findMaxGCD(int arr[], int n)
    {
        // Calculating MAX in
        // array
        int high = 0;
        for (int i = 0; i < n; i++)
            high = Math.max(high, arr[i]);
     
        // Maintaining count array
        int count[]=new int[high + 1];
        for (int i = 0; i < n; i++)
            count[arr[i]]++;
     
        // Variable to store
        // the multiples of
        // a number
        int counter = 0;
     
        // Iterating from MAX
        // to 1 GCD is always
        // between MAX and 1
        // The first GCD found
        // will be the highest
        // as we are decrementing
        // the potential GCD
        for (int i = high; i >= 1; i--)
        {
            int j = i;
     
            // Iterating from current
            // potential GCD till it
            // is less than MAX
            while (j <= high)
            {
                // A multiple found
                if (count[j]>0)    
                    counter+=count[j];        
     
                // Incrementing potential
                // GCD by itself
                // To check i, 2i, 3i....
                j += i;
     
                // 2 multiples found,
                // max GCD found
                if (counter == 2)        
                    return i;
            }
            counter=0;
        }
    return 1;
    }
     
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        // Array in which pair
        // with max GCD is to
        // be found
        int arr[] = {1, 2, 4, 8, 8, 12};
     
        // Size of array
        int n = arr.length;
     
        System.out.println(findMaxGCD(arr,n));
    }
}
 
// This code is contributed by Arnav Kr. Mandal.

Python3

# Python3 Code to
# Find pair with
# maximum GCD in
# an array
 
# function to find
# GCD of pair with
# max GCD in the
# array
def findMaxGCD(arr, n) :
     
    # Calculating MAX in
    # array
    high = 0
    for i in range(0, n) :
        high = max(high, arr[i])
 
    # Maintaining count array
    count = [0] * (high + 1)
    for i in range(0, n) :
        count[arr[i]]+=1
 
    # Variable to store the
    # multiples of a number
    counter = 0
 
    # Iterating from MAX
    # to 1 GCD is always
    # between MAX and 1
    # The first GCD found
    # will be the highest
    # as we are decrementing
    # the potential GCD
    for i in range(high, 0, -1) :
        j = i
 
        # Iterating from current
        # potential GCD till it
        # is less than MAX
        while (j <= high) :
 
            # A multiple found
            if (count[j] >0) :
                counter+=count[j]   
 
            # Incrementing potential
            # GCD by itself
            # To check i, 2i, 3i....
            j += i
 
            # 2 multiples found,
            # max GCD found
            if (counter == 2) :
                return i
        counter=0
         
# Driver code
 
# Array in which pair
# with max GCD is to
# be found
arr = [1, 2, 4, 8, 8, 12]
# Size of array
n = len(arr)
print(findMaxGCD(arr, n))
 
#This code is contributed by Nikita Tiwari.

C#

// C# Code to find pair with
// maximum GCD in an array
using System;
 
class GFG {
     
    // function to find GCD
    // of pair with max
    // max GCD in the array
    public static int findMaxGCD(int []arr,
                                int n)
    {
        // Calculating Max
        // in array
        int high = 0;
        for (int i = 0; i < n; i++)
            high = Math.Max(high, arr[i]);
     
        // Maintaining count array
        int []count=new int[high + 1];
        for (int i = 0; i < n; i++)
            count[arr[i]]++;
     
        // Variable to store
        // the multiples of
        // a number
        int counter = 0;
     
        // Iterating from MAX
        // to 1 GCD is always
        // between MAX and 1
        // The first GCD found
        // will be the highest
        // as we are decrementing
        // the potential GCD
        for (int i = high; i >= 1; i--)
        {
            int j = i;
     
            // Iterating from current
            // potential GCD till it
            // is less than MAX
            while (j <= high)
            {
                // A multiple found
                if (count[j]>0)    
                    counter+=count[j];    
     
                // Incrementing potential
                // GCD by itself
                // To check i, 2i, 3i....
                j += i;
     
                // 2 multiples found,
                // max GCD found
                if (counter == 2)    
                    return i;
            }
            counter=0;
        }
    return 1;
    }
     
    // Driver Code
    public static void Main(String []args)
    {
        // Array in which pair
        // with max GCD is to
        // be found
        int []arr = {1, 2, 4, 8, 8, 12};
     
        // Size of array
        int n = arr.Length;
     
        Console.WriteLine(findMaxGCD(arr,n));
    }
}
 
// This code is contributed by vt_m.

的PHP

= 1; $i--)
    {
        $j = $i;
        $counter = 0;
 
        // Iterating from current potential GCD
        // till it is less than MAX
        while ($j <= $high)
        {
            // A multiple found
 
            if($count[$j] >= 2)
            return $j;
 
        else if ($count[$j] == 1)    
                $counter++;    
 
            // Incrementing potential GCD by itself
            // To check i, 2i, 3i....
            $j += $i;
 
            // 2 multiples found, max GCD found
            if ($counter == 2)    
                return $i;
        }
    }
}
 
// Driver code
 
// Array in which pair with max GCD
// is to be found
$arr = array( 1, 2, 4, 8, 8, 12 );
 
// Size of array
$n = count($arr);
 
print(findMaxGCD($arr, $n));
 
// This code is contributed by mits
?>

Java脚本


输出:

8