我们得到一个n个整数的排序数组A [1..n]。我们说元素x E A很少发生 在A严格不到n / 10倍。也就是说,如果存在某个索引1< = i< = n,则x很少见 A(i)= x,并且严格地小于n / 10个不同的索引j,其中A(j)= x。我们的目标 是找到稀有元素,或输出A不包含稀有元素。
输入:n个整数的排序数组A [1..n]。
输出:稀有元素x E A,或输出“A中不存在稀有元素。”
稀有元素问题是否有O(log n)时间算法?它是什么?
T(n)= 10 T(n / 10)+ O(1)给出O(n)时间对我来说不够好。
答案 0 :(得分:2)
是的,可以在O(log n)
中执行此操作。我假设你已经在内存中有这个数组了。否则,它不可能比O(n)
更快地完成,因为你至少需要读取数组。
让我们说step
是小于n/10
的最大整数。如果step
等于零,那么我们显然没有稀有元素。
考虑以下算法:
int start = 1;
while (true) {
if (n - start + 1 <= step) {
OutputRare(A[start]); Exit;
}
int next_index = start + step;
if (A[start] != A[next_index]) {
OutputRare(A[start); Exit;
}
// Here we need to find the smallest index starting from start with
// element that is not equal to A[start]. If such element does not
// exist function returns -1.
next_index = FindFirstNonEqual(A[start], start);
if (next_index == -1) {
// There is no rare elements
Exit;
}
start = next_index;
}
此算法要么返回稀有元素,要么至少增加step
。这意味着它会增加〜10倍(因为每一步都是n/10
)。 FindFirstNonEqual
可以使用二进制搜索来实现,这意味着总复杂度为O(10log n) = O(log n)
。