在时间 O(n) 中查找数组中的重复元素
我在求职面试中被问到这个问题,我一直在想正确的答案。
您有一个从 0 到 n-1 的数字数组,其中一个数字被删除,并替换为数组中已有的数字,该数字与该数字重复。我们如何在时间O(n)中检测到这种重复?
例如,的数组将变为 。4,1,2,3
4,1,2,2
时间 O(n2) 的简单解决方案是使用嵌套循环来查找每个元素的副本。
我在求职面试中被问到这个问题,我一直在想正确的答案。
您有一个从 0 到 n-1 的数字数组,其中一个数字被删除,并替换为数组中已有的数字,该数字与该数字重复。我们如何在时间O(n)中检测到这种重复?
例如,的数组将变为 。4,1,2,3
4,1,2,2
时间 O(n2) 的简单解决方案是使用嵌套循环来查找每个元素的副本。
这可以在时间和空间上完成。O(n)
O(1)
(该算法之所以有效,是因为数字是已知范围内的连续整数):
在通过向量的单次传递中,计算所有数字的总和,以及所有数字的平方和。
从 中减去所有数字的总和。称之为 .N(N-1)/2
A
从 中减去平方和。将其除以 。调用结果 。N(N-1)(2N-1)/6
A
B
被删除的号码是,它被替换的号码是 。(B + A)/2
(B - A)/2
向量是:[0, 1, 1, 2, 3, 5]
N = 6
向量的总和为 0 + 1 + 1 + 2 + 3 + 5 = 12。N(N-1)/2 为 15。A = 3。
平方和为 0 + 1 + 1 + 4 + 9 + 25 = 40。N(N-1)(2N-1)/6 为 55。B = (55 - 40)/A = 5。
删除的数字是 (5 + 3) / 2 = 4。
它被替换为的数字是 (5 - 3) / 2 = 1。
原始向量的总和为 。假设该值已被删除并替换为 。现在,修改后的向量的总和将为 。如果我们从中减去修改向量的总和,我们得到。所以。[0, ..., N-1]
N(N-1)/2
a
b
N(N-1)/2 + b - a
N(N-1)/2
a - b
A = a - b
同样,原始向量的平方和为 。修改向量的平方和为 。从原始和中减去修正向量的平方和,得到 ,这与 相同。因此,如果我们将其除以(即),我们得到。N(N-1)(2N-1)/6
N(N-1)(2N-1)/6 + b2 - a2
a2 - b2
(a+b)(a-b)
a - b
A
B = a + b
现在和 .B + A = a + b + a - b = 2a
B - A = a + b - (a - b) = 2b
我们有原始数组 创建第二个数组 类型为 。迭代第一个数组并设置 if 是 false,否则 bing!int A[N];
bool B[N]
bool=false
B[A[i]]=true