📅  最后修改于: 2023-12-03 14:54:58.575000             🧑  作者: Mango
在一个给定的数组中,找到所有满足 a/b=b/c 的三元组(a,b,c)的数量。
一种简单的解法是三重循环枚举 a,b,c,并检查 a/b=b/c,但这样的时间复杂度为 O(N^3),无法通过高效性测试。
更好的解法是使用字典(Python 中的 dict 或者 C++ 中的 unordered_map),以 b 为键存储所有可以除尽 b 的数字 a,然后对于每个 b,在字典中查找可以被 b 整除的 c,计算所有可能的三元组数量,并将它们累加到结果中。
def count_triples(arr):
dict_b = {}
for a in arr:
if a % arr[0] == 0:
dict_b[arr[0]] = [a]
else:
for b in dict_b:
if a % b == 0:
dict_b[b].append(a)
count = 0
for b in dict_b:
bs = set(dict_b[b])
if len(bs) < 2:
continue
for a in bs:
for c in bs:
if a != c and a * b == c * b:
count += 1
return count
这个算法的时间复杂度为 O(N^2)。
#include <unordered_map>
#include <vector>
using namespace std;
int count_triples(vector<int>& arr) {
unordered_map<int, vector<int>> dict_b;
for (int a : arr) {
if (a % arr[0] == 0) {
dict_b[arr[0]] = {a};
} else {
for (auto& p : dict_b) {
int b = p.first;
if (a % b == 0) {
p.second.push_back(a);
}
}
}
}
int count = 0;
for (auto& p : dict_b) {
int b = p.first;
vector<int>& bs = p.second;
if (bs.size() < 2) {
continue;
}
unordered_map<int, int> dict_c;
for (int c : bs) {
dict_c[c]++;
}
for (int a : bs) {
for (int c : bs) {
if (a != c) {
if (dict_c[a * b / c] > 0) {
count += dict_c[a * b / c];
}
}
}
}
}
return count;
}
使用字典可以大大优化计算三元组的时间复杂度,但实现上需要考虑边界情况(比如字典中只有一个元素的情况)和重复计数的问题(比如重复计算 (a, b, c) 和 (c, b, a))。