生成一个 N 长度数组,其所有对的 GCD 都存在于给定的 2D 数组中
给定一个由N*N正整数组成的二维数组arr[][] ,任务是生成一个长度为 N 的数组,使得该数组的所有可能对的最大公约数 (GCD) 都存在于数组arr[] [] 。
例子:
Input: N = 4, arr[] = {2, 1, 2, 3, 4, 3, 2, 6, 1, 1, 2, 2, 1, 2, 3, 2}
Output: 4, 3, 6, 2
Explanation:
Considering the array A[] as {4, 3, 6, 2}, then the GCD of all possible pairs of this array is given below which is the given array arr[].
{{4, 1, 2, 2},
{1, 3, 3, 1},
{2, 3, 6, 2},
{2, 1, 2, 2}}
Input: N = 1, mat = {100}
Output: 100
方法:上述问题可以通过以下事实来解决:原始数组中最大元素与自身的GCD在arr[]中最大,并且在删除与该元素的gcd对后,可以找到下一个元素。请按照以下步骤解决给定的问题:
- 初始化一个映射说, M存储映射M中数组元素的否定频率。
- 初始化一个变量,比如pos为(N – 1) 。
- 现在,对于所有数组元素arr[]找到最大元素。
- 遍历地图M。
- 对于原始数组的每个元素,找到频率最大的元素,并将其存储在 ans 中。
- 找到ans[pos]并删除从ans的pos+1到N-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 )