📜  查找给定 Array 的每个子序列的所有可能的 GCD

📅  最后修改于: 2022-05-13 01:57:48.652000             🧑  作者: Mango

查找给定 Array 的每个子序列的所有可能的 GCD

给定一个由N个正整数组成的数组arr[] ,任务是在数组arr[]的所有非空子序列中找到所有可能的不同最大公约数 (GCD)

例子:

朴素方法:解决给定问题的最简单方法是生成给定数组的所有可能子序列,并将子序列的所有 GCD 存储在一个集合中。检查所有子序列后,将集合中的元素存储打印为所有可能形成的 GCD。

时间复杂度: O(log M*2 N ),其中 M 是数组的最大元素
辅助空间: O(1)

有效方法:上述方法也可以使用贪心方法进行优化,方法是观察任何子序列的 GCD 位于[1, M]范围内,其中M是数组的最大元素。因此,想法是遍历范围[1, M] ,如果范围内的任何元素是数组元素的一个因子,则将当前元素打印为结果GCD之一。请按照以下步骤解决问题:

  • 将所有数组元素存储在 HashSet 中,例如s
  • 使用变量i迭代范围[1, M]并执行以下步骤:
    • 遍历i的所有倍数,如果 HashSet 中存在任何倍数,则打印当前元素i作为可能的 GCD 之一。

以下是上述方法的实现:

// 上述方法的 C++ 程序

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the different GCDs of
// the subsequence of the given array
void findGCDsSubsequence(vector arr)
{
     
    // Stores all the possible GCDs
    vector ans;
 
    // Stores all array element in set
    set s;
    for(int i : arr)
        s.insert(i);
         
    int M = *max_element(arr.begin(), arr.end());
     
    // Iterate over the range [1, M]
    for(int i = 1; i <= M; i++)
    {
        int gcd = 0;
 
        // Check if i can be the GCD of
        // any subsequence
        for(int j = i; j < M + 1; j += i)
        {
            if (s.find(j) != s.end())
                gcd = __gcd(gcd, j);
        }
        if (gcd == i)
            ans.push_back(i);
    }
    for(int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
}
 
// Driver Code
int main()
{
    int N = 7;
    vector arr = { 3, 4, 8 };
 
    // Function Call
    findGCDsSubsequence(arr);
    return 0;
}
 
// This code is contributed by parthagarwal1962000


Java
// Java program for the above approach
import java.util.*;
public class GFG {
static int gcd1(int a, int b)
{
    return b == 0 ? a : gcd1(b, a % b);
}
 
// Function to find the different GCDs of
// the subsequence of the given array
static void findGCDsSubsequence(ArrayList arr)
{
     
    // Stores all the possible GCDs
    ArrayList ans = new ArrayList();
 
    // Stores all array element in set
    HashSet s = new HashSet();
    for(int i : arr)
        s.add(i);
         
    int M = Integer.MIN_VALUE;
    for(int i : arr)
    {
        if (i > M)
            M = i;
    }
 
    // Iterate over the range [1, M]
    for(int i = 1; i <= M; i++)
    {
        int gcd = 0;
 
        // Check if i can be the GCD of
        // any subsequence
        for(int j = i; j < M + 1; j += i)
        {
            if (s.contains(j))
                gcd = gcd1(gcd, j);
        }
        if (gcd == i)
            ans.add(i);
    }
    for(int i = 0; i < ans.size(); i++)
       System.out.print(ans.get(i) + " ");
}
 
// Driver Code
 public static void main(String args[])
{
    ArrayList arr = new ArrayList();
    arr.add(3);
    arr.add(4);
    arr.add(8);
 
    // Function Call
    findGCDsSubsequence(arr);
}
}
// This code is contributed by SoumikMondal


Python3
# Python3 program for the above approach
import math
 
# Function to find the different GCDs of
# the subsequence of the given array
def findGCDsSubsequence(nums):
 
        # Stores all the possible GCDs
    Ans = []
 
    # Stores all array element in set
    s = set(nums)
 
    # Find the maximum array element
    M = max(nums)
 
    # Iterate over the range [1, M]
    for i in range(1, M + 1):
       
          # Stores the GCD of subsequence
        gcd = 0
 
        # Check if i can be the GCD of
        # any subsequence
        for j in range(i, M + 1, i):
            if j in s:
                gcd = math.gcd(gcd, j)
 
        # Store the value i in Ans[]
        # if it can be the GCD
        if gcd == i:
            Ans += [i]
 
    # Print all possible GCDs stored
    print(*Ans)
 
 
# Driver Code
N = 7
arr = [3, 4, 8]
 
# Function Call
findGCDsSubsequence(arr)


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
static int gcd1(int a, int b)
{
    return b == 0 ? a : gcd1(b, a % b);
}
 
// Function to find the different GCDs of
// the subsequence of the given array
static void findGCDsSubsequence(List arr)
{
     
    // Stores all the possible GCDs
    List ans = new List();
 
    // Stores all array element in set
    HashSet s = new HashSet();
    foreach(int i in arr)
        s.Add(i);
         
    int M = Int32.MinValue;
    foreach(int i in arr)
    {
        if (i > M)
            M = i;
    }
 
    // Iterate over the range [1, M]
    for(int i = 1; i <= M; i++)
    {
        int gcd = 0;
 
        // Check if i can be the GCD of
        // any subsequence
        for(int j = i; j < M + 1; j += i)
        {
            if (s.Contains(j))
                gcd = gcd1(gcd, j);
        }
        if (gcd == i)
            ans.Add(i);
    }
    for(int i = 0; i < ans.Count; i++)
        Console.Write(ans[i] + " ");
}
 
// Driver Code
public static void Main()
{
    List arr = new List(){ 3, 4, 8 };
 
    // Function Call
    findGCDsSubsequence(arr);
}
}
 
// This code is contributed by SURENDRA_GANGWAR


Javascript


输出
1 3 4 8

时间复杂度: O(M*log M),其中 M 是数组的最大元素
辅助空间: O(N)