在C中找到两次数字的最快方法

时间:2016-09-16 13:50:51

标签: c

任何人都可以帮我解决如何用C解决这个问题吗?我认为我必须使用大O符号作为解决方案,但我不知道它。

问题:有一个T大小为N + 1的数组,其中从1到N的数字是随机的。一个数字x重复两次(位置也是随机的)。

找到这个数字x值的最快方法是什么?

例如: N = 7

[6 3 5 1 3 7 4 2]

X = 3

3 个答案:

答案 0 :(得分:4)

数字1..N的总和是N *(N + 1)/ 2。

所以,额外的数字是:

DataActivity

除了总和之外,一切都是O(1)。总和可以在O(N)时间内计算。

整体算法为O(N)。

答案 1 :(得分:0)

Klaus给出的算法具有O(1)内存要求,但需要对给定数组中的所有元素求和,这些元素可能非常大,可以在它们上面迭代(求和)。

另一种方法是迭代数组并在每次迭代时递增出现计数器一次,因此一旦找到重复数据就可以立即停止 ,尽管最坏的情况是扫描所有的元素。例如:

#define N 8

int T[N] = {6, 3, 5, 1, 3, 7, 4, 2};

int occurences[N+1] = {0};
int duplicate = -1;
for (int i = 0; i < N; i++) {
    occurences[T[i]]++;
    if (occurences[T[i]] == 2) {
        duplicate = T[i];
        break;
    }
}

请注意,此方法也不受整数溢出的影响,即N*(N+1)/2.可能大于整数数据类型可能容纳的值。

答案 2 :(得分:0)

使用值作为下一个数组索引(减1)来遍历数组,使用特殊值(如0或否定)标记访问的数组。 O(n)

average 上,只访问了一半的元素。

v
6 3 5 1 3 7 4 2

            v
. 3 5 1 3 7 4 2

        v   
. 3 5 1 3 7 . 2

      v
. 3 5 1 . 7 . 2

  v
. 3 5 . . 7 . 2

      v !! all ready visited.  Previous 3 is repeated.
. 3 5 . . 7 . 2

加总和不会导致溢出问题。当然需要修改数组(或者需要兄弟bool标志数组。)

即使重复超过1个值,此方法仍然有效。