C++ 计数乘积为x的三元组数
给定一个整数数组和一个整数x,我需要找到数组中乘积为x的无序三元组的数目。我有一个强力O(n3)解决方案:C++ 计数乘积为x的三元组数,c++,algorithm,data-structures,C++,Algorithm,Data Structures,给定一个整数数组和一个整数x,我需要找到数组中乘积为x的无序三元组的数目。我有一个强力O(n3)解决方案: int solve(int a[], int n, int x) { int ans = 0; for (int i = 0; i < n; ++i) for (int j = i+1; j < n; ++j) for (int k = j+1; k < n; ++k) if(a[i]
int solve(int a[], int n, int x) {
int ans = 0;
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
for (int k = j+1; k < n; ++k)
if(a[i]*a[j]*a[k] == x)
ans++;
return ans;
}
intsolve(inta[],intn,intx){
int ans=0;
对于(int i=0;i
有没有一种更快的方法,比如在O(n logn)时间内
运行时间现在将取决于素数pf(x)的数量,特别是O(3^pf(x))。由于x的素数因子的数量可以用log(x)来限定,这就产生了O(3^log(x)),这实际上可以进一步简化,具体取决于精确的基数。代码是java的,但正如您所知,其思想是一样的 时间复杂度为
O(n^1.5)
。我用10^5个元素进行了检查,结果正常。
这个想法是-
- 将列表中的所有元素及其计数放入映射中李>
- 现在,如果
为a[i]*a[j]*a[k]==x
,那么这三个都必须是true
的因子。因此,如果x
,我会在x%a[i]==0
时间中查找所有乘以sqrt(x/a[i])
的因子(对)x/a[i]
- 因为,我们对列表中的每个元素都这样做,复杂性如下-
- O(n)用于向映射添加元素
- O(n*n^0.5)用于检查三胞胎李>
import java.util.*;
import java.io.*;
class Solution{
public static void main(String args[]) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] s = br.readLine().split("\\s");
int[] a = new int[n];
for(int i=0;i<n;++i){
a[i] = Integer.parseInt(s[i]);
}
int x = Integer.parseInt(br.readLine());
System.out.println(solve(a,n,x));
}
private static long solve(int a[], int n, int x) {
long tuples = 0;
Map<Integer,Integer> elements = new HashMap<>();
for(int i=0;i<a.length;++i){
elements.put(a[i],elements.getOrDefault(a[i],0) + 1);
}
for(int i=0;i<a.length;++i){
if(x%a[i] == 0){
tuples += factorPairs(x/a[i],elements,a[i]);
}
}
return tuples;
}
private static long factorPairs(int x,Map<Integer,Integer> elements,int factor1){
long pairs = 0;
for(int i=1;i*i<=x;++i){
int second = i;
int third = x/i;
if(second*third == x && elements.containsKey(second) && elements.containsKey(third)){
long second_cnt = elements.get(second) - (second == factor1 ? 1 : 0);
long third_cnt = elements.get(third) - (third == factor1 ? 1 : 0);
pairs += second_cnt * third_cnt;
}
}
return pairs;
}
}
import java.util.*;
导入java.io.*;
类解决方案{
公共静态void main(字符串args[])引发IOException{
BufferedReader br=新的BufferedReader(新的InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
字符串[]s=br.readLine().split(\\s);
int[]a=新的int[n];
对于(int i=0;我给我们举个例子。对于nlog(n)
,排序并可能进行二进制搜索。一旦对数字进行排序,可以在线性时间内完成。要改进O(n^3),需要一些假设。发布你的暴力O(n^3)解决方案和样本数据集以及预期的输出将使许多假设更加清晰。问题很广泛。@SaiBot:我认为OP想要三元组,而不是成对的。你可以将其设为O(n^2)。它不是pf(x)^3吗?不,你不想从pf(x)中选择3个元素,但你想从pf(x)中构建3个组数字。从N个元素中生成3个组有3个^ ^可能性。@ Juviang-On,我在这里混合了主要因子和除数。我的坏。是的,我也感到困惑:)对不起,不是一个大的C++程序员。另外,StAdSoad不应该是一个编码服务。试试你自己,如果你遇到问题,人们会帮助。