我有N个号码,请说20 30 15 30 30 40 15 20
。现在我想找出给定范围内有多少个数字对。( L 和 R 给出)。
数字对=两个数字相同。
我的方法:
创建一个数组地图,使键 =数字,值 =显示该数字的索引的ArrayList。然后我从L遍历到R并且对于该范围中的每个值,我遍历相应的arraylist以查找是否存在适合范围的对,然后递增计数。
但我认为这种做法太慢了。有没有更快的方法来做同样的事情?
示例:对于上面给出的序列,L = 0且R = 6 答案= 5。可能的对为1为20,1为15和3为30。
我正在开发一个解决方案,假设数字可以达到10 ^ 8(非负数)。
答案 0 :(得分:0)
如果你正在寻找速度而不关心记忆,那么可能有更好的方法。
您可以使用set作为辅助数据结构来查看是否找到了数字,然后只需遍历数组。伪代码:
int numPairs = 0;
set setVisited;
for (int i = L; i < R; i++) {
if (setVisited.contains(a[i])) {
// found the second of a pair. count it up and reset.
numPairs++;
setVisited.remove(a[i]);
} else {
// remember that we saw this number, so we can spot the next pair.
setVisited.add(a[i]);
}
答案 1 :(得分:0)
新解决方案......希望这次更好。 Psuedo C-ish代码:
{{1}}
排序运行O(nlgn),循环体运行O(n)。有趣的是,性能障碍现在是阶乘的。对于具有非常多次出现次数的真正长阵列,除非进一步优化,否则阶乘是昂贵的。
一种方法是循环计数重复但不计算因子 - 留下另一组数字计数。然后对此数组进行排序(再次为Nlg(N)),然后遍历此数组并重新使用先前计算的factorial来计算下一个数组。
此外,如果此数组变大,您需要一个大整数来表示总数。我不知道我头顶的大整数的O()表现。
很酷的问题!