火车站距离中心的距离等于N英里

时间:2015-12-27 15:12:36

标签: arrays algorithm search

我有一个非常庞大的正整数数组,表示某个火车站距离中心的距离,例如:

"false"

火车站S [0]距离市中心10英里。 S在升序顺序中,始终在任何时间点排序,也在算法开始之前排序。只是一直。

我想找一个功能来检查是否存在两个距离恰好为N英里的火车站。

例如: N = 1300会给我真实,因为1500 - 200 = 1300。

第一种方法

迭代S并检查每个元素,如果到另一个元素的距离是N.这给了我两个循环,我猜O(n ^ 2)。我不想要O(n ^ 2),因为数组可能非常庞大,需要更好的性能。

其他方法

我做了很多研究,但我发现只有O(n)是可能的。我希望这个时间复杂。我的解决方案看起来像这样,但遗憾的是它根本无法解决。

true

3 个答案:

答案 0 :(得分:3)

只需递增两个指针O(n)i,即可实现线性时间(j)。您希望ij找到a[j] - a[i] == N。逻辑很简单:

  • 如果a[j] - a[i] < N:增量j(距离变大)
  • 如果a[j] - a[i] > N:增量i(距离变小)

这就是全部!在代码中:

int i = 0;
int j = 0;

while ((a[j] - a[i] != N) && j < size) { // size is length of a
    if (a[j] - a[i] < N) {
        j++;
    } else {
        i++;
    }
}

if (j < size) {
    printf("found pair: %d %d\n", i, j);
}

手握正确性证明:原则上,我们应该针对可能提供解决方案的所有a[j]检查每个a[i]。也就是说,对于每个j,我们会检查范围p_j <= i <= q_j,例如a[j] - a[p_j] > Na[j] - a[q_j] < N。如果存在涉及j的解决方案,则必须在i值范围内找到该解决方案。

现在,这个算法几乎可以做到这一点,但有一个例外:有时我们连续多次递增j,所以我们显然没有在整个范围内检查它。我们再次增加j,因为a[j] - a[i] < N。但是,如果发生这种情况,我们也知道a[j] - a[i-1] > N。我留给你核实这个。

这意味着我们会针对可能提供解决方案的所有j值范围检查i。结果是正确的。

我们有两个指针。在每个步骤中,一个指针递增。 2(j)中较大者的大小由n限定,因此在O(n)时间内运行。

答案 1 :(得分:0)

sum应更改为distance
它应该是:

if(distance < N) {
  right--;
  left--;
}

不仅仅是

if(distance < N)
  right--;

答案 2 :(得分:0)

此代码块中存在错误:

if (distance < N)
    right--;

您还希望在此处减少left的值:

if (distance < N)
{
    right--;
    left--;
}

此外,第12行中的变量sum应为distance