任何人都可以帮我解决如何用C解决这个问题吗?我认为我必须使用大O符号作为解决方案,但我不知道它。
问题:有一个T大小为N + 1的数组,其中从1到N的数字是随机的。一个数字x重复两次(位置也是随机的)。
找到这个数字x值的最快方法是什么?
例如: N = 7
[6 3 5 1 3 7 4 2]
X = 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个值,此方法仍然有效。