问题:
让
A = A[1]<=A[2]....A[n]
成为n
个数字的排序数组。设x
为数字。设计O(log n)
时间算法以查找x
在数组中出现的次数。什么是时间复杂度。
我的回答:
使用二进制搜索查找x = middle
。如果x
位于中间,那么x
可能会出现在中间的左侧和右侧。因此,创建左数组L[]
和右数组R[]
。使用二进制搜索会在x
中第一次找到L[]
。对R[]
执行相同操作,但查找x
中最后一次出现R[]
。注意索引。因此x
出现的时间= Lastindex - FirstIndex + 1
。时间复杂度2log n + c = O(log n)。它只是算法的“骨架部分”,因为答案无需详细阐述。这是我发现的,但有更好的解决方案吗?
答案 0 :(得分:0)
使用二分搜索来找到第一个元素&gt; = x的位置(如果没有这样的元素则结束),另一个二元搜索找到第一个元素的位置&gt; X。这些位置之间的差异是元素数量== x。
int countXs(int[] array, int len, int x)
{
int low, high, test;
for (low=0, high=len; low<high;)
{
test = low+((high-low)>>1);
if (array[test]>=x)
high=test;
else
low=test+1;
}
int startPos = low;
for (low=0, high=len; low<high;)
{
test = low+((high-low)>>1);
if (array[test]>x)
high=test;
else
low=test+1;
}
int endPos = low;
return endPos - startPos;
}
请注意low+((high-low)>>1)
为floor((low+high)/2)
,但不受溢出的影响。这始终是>= low
和< high
,因此我们可以安全地访问array[test]
。