查找给定范围内的所有数字对

时间:2015-05-16 14:27:22

标签: algorithm array-algorithms

我有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(非负数)。

2 个答案:

答案 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()表现。

很酷的问题!