给定两个数组arr1[]和arr2[] 。我们可以通过将数组arr1[]的每个元素添加到每个元素arr2[]来生成另一个数组arr3 [] 。任务是找到数组arr3[]中不同元素的计数。
例子:
Input: Arr1[] = {1, 2}, Arr2[] = {3, 4}, MAX = 4
Output:
4 -> 1
5 -> 2
6 -> 1
Explanation:
Here the third array will be Arr3[] = {1+3, 1+4, 2+3, 2+4} = {4, 5, 5, 6}
Input: Arr1[] = {1, 2}, Arr2[] = {1, 2, 1}, MAX = 2
Output:
2 -> 2
3 -> 3
4 -> 1
Explanation:
Here the third array is Arr3[] = {1+1, 1+2, 1+1, 2+1, 2+2, 2+1} = {2, 3, 2, 3, 4, 3}
Therefore Count of elements from 1 to 2*2 (4) are {0, 2, 3, 1}
朴素的方法:朴素的方法是从给定的两个数组中找到所有可能对的总和,并将该总和插入到数组arr3[] 中。打印数组arr3[]的所有元素的频率。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find Occurrence of each
// element from 1 to 2*MAX
void findCount(vector& Arr1,
vector& Arr2)
{
// Initialise MAX
int MAX = max(*max_element(Arr1.begin(),
Arr1.end()),
*max_element(Arr2.begin(),
Arr2.end()));
// Count vector to store count of
// each element from 1 to 2*MAX
vector Count(2 * MAX + 1, 0);
// Size of Arr1 and Arr2
int n = Arr1.size(), m = Arr2.size();
// Find the elements of arr3[] and
// increase count of element by 1
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int element = Arr1[i] + Arr2[j];
Count[element]++;
}
}
// Print the result
for (int i = 1; i <= 2 * MAX; i++) {
if (Count[i] > 0) {
cout << i << "->"
<< Count[i] << endl;
}
}
}
// Driver Code
int main()
{
// Given arrays arr1[] and arr2[]
vector arr1 = { 1, 2 };
vector arr2 = { 1, 2, 1 };
// Function Call
findCount(arr1, arr2);
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find Occurrence of each
// element from 1 to 2*MAX
static void findCount(int[] Arr1, int[]Arr2)
{
// Initialise MAX
int MAX = Math.max(Arrays.stream(Arr1).max().getAsInt(),
Arrays.stream(Arr2).max().getAsInt());
// Count vector to store count of
// each element from 1 to 2*MAX
int[] Count = new int[2 * MAX + 1];
// Size of Arr1 and Arr2
int n = Arr1.length, m = Arr2.length;
// Find the elements of arr3[] and
// increase count of element by 1
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
int element = Arr1[i] + Arr2[j];
Count[element]++;
}
}
// Print the result
for(int i = 1; i <= 2 * MAX; i++)
{
if (Count[i] > 0)
{
System.out.print(i + "->" +
Count[i] + "\n");
}
}
}
// Driver Code
public static void main(String[] args)
{
// Given arrays arr1[] and arr2[]
int[] arr1 = { 1, 2 };
int[] arr2 = { 1, 2, 1 };
// Function call
findCount(arr1, arr2);
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 program for the above approach
# Function to find Occurrence of each
# element from 1 to 2*MAX
def findCount(Arr1, Arr2):
# Initialise MAX
MAX = max(max(Arr1), max(Arr2));
# Count vector to store count of
# each element from 1 to 2*MAX
#Count = new int[2 * MAX + 1];
Count = [0 for i in range(2 * MAX + 1)]
# Size of Arr1 and Arr2
n = len(Arr1);
m = len(Arr2);
# Find the elements of arr3 and
# increase count of element by 1
for i in range(n):
for j in range(m):
element = Arr1[i] + Arr2[j];
Count[element]+=1;
# Prthe result
for i in range(1,2*MAX+1):
if (Count[i] > 0):
print(i , "->" , Count[i]);
# Driver Code
if __name__ == '__main__':
# Given arrays arr1 and arr2
arr1 = [1, 2 ];
arr2 = [ 1, 2, 1 ];
# Function call
findCount(arr1, arr2);
# This code is contributed by Rohit_ranjan
C#
// C# program for the above approach
using System;
using System.Linq;
class GFG{
// Function to find Occurrence of each
// element from 1 to 2*MAX
static void findCount(int[] Arr1, int[]Arr2)
{
// Initialise MAX
int MAX = Math.Max(Arr1.Max(), Arr2.Max());
// Count vector to store count of
// each element from 1 to 2*MAX
int[] Count = new int[2 * MAX + 1];
// Size of Arr1 and Arr2
int n = Arr1.Length, m = Arr2.Length;
// Find the elements of arr3[] and
// increase count of element by 1
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
int element = Arr1[i] + Arr2[j];
Count[element]++;
}
}
// Print the result
for(int i = 1; i <= 2 * MAX; i++)
{
if (Count[i] > 0)
{
Console.Write(i + "->" +
Count[i] + "\n");
}
}
}
// Driver Code
public static void Main(String[] args)
{
// Given arrays arr1[] and arr2[]
int[] arr1 = { 1, 2 };
int[] arr2 = { 1, 2, 1 };
// Function call
findCount(arr1, arr2);
}
}
// This code is contributed by Princi Singh
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
using cd = complex;
// Value of PI need in FFT
const double PI = acos(-1);
// Function to implement the FFT
void fft(vector& a, bool invert)
{
int n = a.size();
if (n == 1)
return;
vector a0(n / 2), a1(n / 2);
for (int i = 0; 2 * i < n; i++) {
a0[i] = a[2 * i];
a1[i] = a[2 * i + 1];
}
// Recursively find fft
fft(a0, invert);
fft(a1, invert);
double ang = 2 * PI / n * (invert ? -1 : 1);
cd w(1), wn(cos(ang), sin(ang));
for (int i = 0; 2 * i < n; i++) {
a[i] = a0[i] + w * a1[i];
a[i + n / 2] = a0[i] - w * a1[i];
if (invert) {
a[i] /= 2;
a[i + n / 2] /= 2;
}
w *= wn;
}
}
// Function to multiply two polynomials
// A(x) and B(x) using FFT
vector multiply(vector const& a,
vector const& b)
{
vector fa(a.begin(), a.end()),
fb(b.begin(), b.end());
int n = 1;
while (n < a.size() + b.size()) {
n <<= 1;
}
// Resize fa and fb
fa.resize(n);
fb.resize(n);
// Assign initially false
fft(fa, false);
fft(fb, false);
for (int i = 0; i < n; i++)
fa[i] *= fb[i];
fft(fa, true);
// To store the result
vector result(n);
for (int i = 0; i < n; i++)
result[i] = round(fa[i].real());
// Return result
return result;
}
// Function to find the Count of each
// element from 1 to 2*MAX
void findCount(vector& Arr1,
vector& Arr2)
{
// Initialise MAX
int MAX = max(*max_element(Arr1.begin(),
Arr1.end()),
*max_element(Arr2.begin(),
Arr2.end()));
int n = Arr1.size();
int m = Arr2.size();
// vector for Polynomial A(x) from Arr1
vector A(MAX + 1);
for (int i = 0; i < n; i++) {
A[Arr1[i]]++;
}
// Vector for Polynomial B(x) from Arr2
vector B(MAX + 1);
for (int i = 0; i < m; i++) {
B[Arr2[i]]++;
}
// Vector to store the result of
// multiplication of A(x) and B(x)
vector P;
// Multiplying Arr1 and Arr2 and
// storing in P is same as Count
P = multiply(A, B);
// Print the result
for (int i = 1; i <= 2 * MAX; i++) {
if (P[i] > 0) {
cout << i << "->"
<< P[i] << endl;
}
}
cout << '\n';
}
// Driver Code
int main()
{
// Given arrays arr1[] and arr2[]
vector arr1 = { 1, 2 };
vector arr2 = { 1, 2, 1 };
// Function Call
findCount(arr1, arr2);
}
2->2
3->3
4->1
时间复杂度: O(N 2 )
空间复杂度: O(N)
高效的解决方案:在 FFT(快速傅立叶变换)的帮助下,可以有效地完成给定的任务。以下是步骤:
- 考虑示例Arr1[] = {1, 2}和Arr2[] = {1, 2, 1} 。令 Count 为频率数组,即 Count[i] 表示结果数组中 i 的频率。
- 当 Arr1[i] 与 Arr2[j] 相加时,我们增加 Count[s],其中 s = Arr1[i]+Arr2[j]。这类似于乘以多项式,因为功率增加了。
- 设 A(x) 是由 Arr1[] 表示的多项式。 Arr1 的元素表示 x 的幂,它们在 Arr1 中的计数是多项式中具有该幂的系数项。
- 对于每一项,x 的幂表示结果元素,系数表示其计数。
- 如果术语是
- 然后 Count[i] = k。这里 Count 与 P(x) 相同。
- 为了计算 P(x) 的值,我们可以简单地乘以 A(x) 和 B(x)。
多项式乘法的朴素方法需要 O(N 2 )。为了使乘法更快,我们可以使用 FFT(快速傅立叶变换)。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
using cd = complex;
// Value of PI need in FFT
const double PI = acos(-1);
// Function to implement the FFT
void fft(vector& a, bool invert)
{
int n = a.size();
if (n == 1)
return;
vector a0(n / 2), a1(n / 2);
for (int i = 0; 2 * i < n; i++) {
a0[i] = a[2 * i];
a1[i] = a[2 * i + 1];
}
// Recursively find fft
fft(a0, invert);
fft(a1, invert);
double ang = 2 * PI / n * (invert ? -1 : 1);
cd w(1), wn(cos(ang), sin(ang));
for (int i = 0; 2 * i < n; i++) {
a[i] = a0[i] + w * a1[i];
a[i + n / 2] = a0[i] - w * a1[i];
if (invert) {
a[i] /= 2;
a[i + n / 2] /= 2;
}
w *= wn;
}
}
// Function to multiply two polynomials
// A(x) and B(x) using FFT
vector multiply(vector const& a,
vector const& b)
{
vector fa(a.begin(), a.end()),
fb(b.begin(), b.end());
int n = 1;
while (n < a.size() + b.size()) {
n <<= 1;
}
// Resize fa and fb
fa.resize(n);
fb.resize(n);
// Assign initially false
fft(fa, false);
fft(fb, false);
for (int i = 0; i < n; i++)
fa[i] *= fb[i];
fft(fa, true);
// To store the result
vector result(n);
for (int i = 0; i < n; i++)
result[i] = round(fa[i].real());
// Return result
return result;
}
// Function to find the Count of each
// element from 1 to 2*MAX
void findCount(vector& Arr1,
vector& Arr2)
{
// Initialise MAX
int MAX = max(*max_element(Arr1.begin(),
Arr1.end()),
*max_element(Arr2.begin(),
Arr2.end()));
int n = Arr1.size();
int m = Arr2.size();
// vector for Polynomial A(x) from Arr1
vector A(MAX + 1);
for (int i = 0; i < n; i++) {
A[Arr1[i]]++;
}
// Vector for Polynomial B(x) from Arr2
vector B(MAX + 1);
for (int i = 0; i < m; i++) {
B[Arr2[i]]++;
}
// Vector to store the result of
// multiplication of A(x) and B(x)
vector P;
// Multiplying Arr1 and Arr2 and
// storing in P is same as Count
P = multiply(A, B);
// Print the result
for (int i = 1; i <= 2 * MAX; i++) {
if (P[i] > 0) {
cout << i << "->"
<< P[i] << endl;
}
}
cout << '\n';
}
// Driver Code
int main()
{
// Given arrays arr1[] and arr2[]
vector arr1 = { 1, 2 };
vector arr2 = { 1, 2, 1 };
// Function Call
findCount(arr1, arr2);
}
2->2
3->3
4->1
时间复杂度: O(N*log N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。