假设我已对数组进行了排序,并且我想计算元素X的出现次数。
伪代码:
SET Lo to 1
SET Hi to array length
WHILE Lo <= Hi
SET Mid to (Lo + Hi) / 2
IF X < array[Mid] THEN
SET Hi to Mid - 1
ELSE IF X > array[Mid] THEN
SET Lo to Mid + 1
ELSE
RETURN Mid
ENDIF
ENDWHILE
RETURN -1
现在假设我想找到数组中所有数字的所有出现但我没有成功。
例如 - A = [1,1,2,2,2,2,5,5,5]返回(1,2),(2,4),(5,3)
算法必须是O(log(n))
帮助
答案 0 :(得分:1)
除非数组非常大并且只包含很少的不同数字,否则只需对数组进行线性扫描即可。每当检测到更改时,输出计数并重置计数器。
对于当前所述的问题,O(log(n))算法是不可能的,因为无论如何到达它,结果的输出在最坏的情况下都已经为O(n)。
答案 1 :(得分:0)
我会做这样的事情:
int nrOfX = 0;
int SortedArray[N];
Lo = 0;
Hi = N-1;
Mid = N-1 div 2;
while (((sortedArray[Lo] < x) or (sortedArray[Hi] > x)) and (Lo != Hi)) {
if (sortedArray[Mid] < x) {
Lo = Mid;
} else if (sortedArray[Mid] > x) {
Hi = Mid;
} else if (sortedArray[Mid] == x) {
Hi = Mid;
Lo = Mid;
}
Mid = (Lo + Hi) div 2;
}
while (sortedArray [Lo - 1] == x) {
Lo--;
}
while (sortedArray [Hi + 1] == x) {
Hi++;
}
if (sortedArray[Lo] == x) {
return ((Hi - Lo) + 1);
} else {
return 0;
}
没有对它进行测试,所以你可能需要调整一下才能使它工作,但一般的想法是你首先得到Lo和Hi到ax值并从那里在不同的方向扩展它们在数组中。如果x根本没有显示,你最终会得到Lo == Hi,因为sortedArray [Lo] == 0这个函数将返回0.如果#x在数组中,这应该在大约O(log N)中运行低。 但是,这仅用于查找1个特定数字的出现次数,即x。如果你想知道所有数字的这个,你会在最坏的情况下得到O(N),因为当它们全部不同时你必须检查每个数字。
答案 2 :(得分:0)
您可以在 O(logn)(最佳情况)和 O(n * logn)最差情况下执行此操作,如下所示: -
- 使用修改后的二进制搜索搜索下一个更大数字(nextind)的索引。
- 存储当前,nextind-currentind
- currentind = nextind和current = arr [nextind]
- 执行1到3直到到达数组末尾
醇>
时间复杂度:
O(m * logn)其中m是数组中唯一数字的计数。如果是 可忽略不计的是O(logn)