📅  最后修改于: 2023-12-03 15:36:02.120000             🧑  作者: Mango
给定一个整数数组,求其中的乘积为完全平方数的不重复数对的个数。
如果两个数乘积为完全平方数,那么它们的质因数分解中,相同的质因数个数必须为偶数个。因此,我们可以对数组中的每个数进行质因数分解,并将同样的质因数合并为一个集合。最终,对所有集合中的数对进行组合,即可得到结果。
因为涉及到质因数分解和集合的操作,我们可以使用 HashMap 来存储每个数的质因数集合,key 为集合的哈希值,value 为集合中的数的个数。然后,对所有集合中的数对进行组合,计算符合条件的数对个数即可。
public int numSquarefulPerms(int[] A) {
int n = A.length;
Map<Integer, Integer> count = new HashMap<>();
Map<Integer, Set<Integer>> factors = new HashMap<>();
for (int num : A) {
count.put(num, count.getOrDefault(num, 0) + 1);
factors.put(num, new HashSet<>());
}
for (int num : count.keySet()) {
for (int factor = 1; factor <= (int) Math.sqrt(num); factor++) {
if (num % factor == 0) {
int anotherFactor = num / factor;
if (count.containsKey(anotherFactor)) {
factors.get(num).add(factor);
factors.get(num).add(anotherFactor);
}
}
}
}
int[] result = {0};
Set<Integer> used = new HashSet<>();
for (int num : count.keySet()) {
backtracking(count, factors, used, num, n - 1, result);
}
return result[0];
}
private void backtracking(Map<Integer, Integer> count, Map<Integer, Set<Integer>> factors, Set<Integer> used, int cur, int remain, int[] result) {
count.put(cur, count.get(cur) - 1);
used.add(cur);
if (remain == 0) {
result[0]++;
} else if (factors.containsKey(cur)) {
for (int factor : factors.get(cur)) {
if (!used.contains(factor) && count.get(factor) > 0) {
backtracking(count, factors, used, factor, remain - 1, result);
}
}
}
used.remove(cur);
count.put(cur, count.get(cur) + 1);
}