新的解决方案......希望这次会更好。伪 C-ish 代码:
// Sort the sub-array a[L..R]. This can be done O(nlogn) using qsort.
// ... code omitted ...
// Walk through the sorted array counting how many times number occurs.
// When the number changes, count how many possibles ways to make pairs
// from the given count.
int totalPairs = 0;
int count = 1;
int current = a[L];
for (i = L+1; i < R; i++) {
if (a[i] == current) { // found another, keep counting
count++;
} else { // found a different one
if (count > 1) { // need at least 2 to make a pair!
totalPairs += factorial(count) / 2;
}
}
// start counting the new one
current = a[i];
count = 1;
}
// count the final one
if (count > 1) {
totalPairs += factorial(count) / 2;
}
排序运行 O(nlgn),循环体运行 O(n)。有趣的是,性能障碍现在是因子。对于出现次数非常多的非常长的数组,除非您进一步优化,否则阶乘是昂贵的。
一种方法是循环计数重复但不计算阶乘——留下另一个数字计数数组。然后对该数组进行排序(再次为 Nlg(N)),然后遍历该数组并重新使用先前计算的阶乘来计算下一个。
此外,如果这个数组变大,您将需要一个大整数来表示总数。我不知道大整数的 O() 性能。
很酷的问题!