📌  相关文章
📜  生成一个 N 长度数组,其所有对的 GCD 都存在于给定的 2D 数组中

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

生成一个 N 长度数组,其所有对的 GCD 都存在于给定的 2D 数组中

给定一个由N*N正整数组成的二维数组arr[][] ,任务是生成一个长度为 N 的数组,使得该数组的所有可能对的最大公约数 (GCD) 都存在于数组arr[] []

例子:

方法:上述问题可以通过以下事实来解决:原始数组中最大元素与自身的GCD在arr[]中最大,并且在删除与该元素的gcd对后,可以找到下一个元素。请按照以下步骤解决给定的问题:

  • 初始化一个映射说, M存储映射M中数组元素的否定频率。
  • 初始化一个变量,比如pos(N – 1)
  • 现在,对于所有数组元素arr[]找到最大元素。
  • 遍历地图M。
  • 对于原始数组的每个元素,找到频率最大的元素,并将其存储在 ans 中。
  • 找到ans[pos]并删除从anspos+1N-1的所有 GCD。
  • pos更新为pos-1
  • 重复上述步骤,找到原始数组的所有元素。
  • 最后,打印ans

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
int n;
  
// Function to calculate GCD of two numbers
int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}
  
// Function to generate an N-length
// array having GCD of all pairs
// present in the array mat[][]
void restoreArray(vector mat)
{
    map cnt;
  
    // Stores the required array
    vector ans(n);
  
    for (int i = 0; i < (n * n); ++i) {
  
        // Store frequencies in map
        // in decreasing order
        cnt[-mat[i]]++;
    }
  
    int pos = n - 1;
  
    for (auto it = cnt.begin();
         it != cnt.end(); ++it) {
  
        int x = -it->first;
        while (it->second) {
  
            // gcd(x, x)
            ans[pos] = x;
            --it->second;
  
            // Remove all GCDs for
            // indices pos + 1 -> n - 1
            for (int i = pos + 1; i < n; ++i)
  
                cnt[-gcd(ans[pos], ans[i])] -= 2;
  
            // Decreasing pos
            pos--;
        }
    }
  
    // Print restored array
    for (int i = 0; i < n; ++i)
        printf("%d ", ans[i]);
}
  
// Driver Code
int main()
{
  
    // Given Input
    n = 4;
    vector mat{ 2, 1, 2, 3, 4, 3,
                     2, 6, 1, 1, 2,
                     2, 1, 2, 3, 2 };
  
    // Function Call
    restoreArray(mat);
    return 0;
}


输出:
2 3 4 6

时间复杂度: O(N 2 LogN)
辅助空间: O(N 2 )