给出一个包含n
个元素的只读数组,找到数组中的中位数(第ceiling(n/2)
个元素,大小为O(logn)
,平均时间为{{1 }}。
我考虑过使用Quicksort的想法,但是如果不更改数组就无法执行它。而复制到另一个数组将超出所需的空间。
答案 0 :(得分:5)
您可以使用分而治之的方法来解决它,在最小值和最大值之间找到一个随机元素,检查它的中位数,是中位数低于还是高于中位数,然后仅在数组的子范围。
将min
设置为数组中的最小元素,并将max
设置为数组中的最大元素。
选择范围(mid
)中的随机数min < mid < max
,如果没有这样的mid
,则min
或max
是中位数,找到完成的工作。
检查min
,mid
或max
中的任何一个是否为中位数(线性搜索,请计算有多少个是大/小)。
3.1。如果是这样,您就完成了。
3.2。否则,中位数在(min,mid)
或(mid,max)
之间,并且您知道位置在哪里(如果高于中间值或低于中间值)。
3.3。如果位于(min,mid)
中,请设置max = mid
,否则,请设置min = mid
。
3.4。返回2。
正确性:
(min,max)
中(带有归纳法的形式证明..),并且保证了每次迭代的范围都会缩小,因此可以保证算法停止并产生一些结果。 / li>
时间复杂度:
O(n)
时间。O(n)
时间(在范围内找到不同的数字)并重复每次迭代。O(n)
时间(遍历每个范围都是线性的)。平均情况下有O(logn)
个迭代(类似于二进制搜索推理)。
这使我们O(nlogn)
的时间复杂度
空间复杂度:
依赖于实现,但是具有尾递归(类似于上面的高级伪代码)实际上可以是O(1)
。对于常规递归,对于堆栈,这是O(logn)
。
答案 1 :(得分:0)
这是一个简单的算法。它包括通过跟踪中间值所在的区间的上下边界来搜索中间值。
让E为元素列表。将中位数的上下限L和U设置为空。
对于E中的每个元素e,
空间复杂度为O(1)。平均时间复杂度最高为O(n 2 )和O(nlogn)。
示例:
E = [2 4 7 9 0 6 5]
L,U = null,null Initial state.
e = 2 L,U = 2,null Update L.
e = 4 L,U = 4,null Update L.
e = 7 L,U = 4,7 Update U.
e = 9 L,U = 4,7 Skip 9.
e = 0 L,U = 4,7 Skip 0.
e = 6 L,U = 4,6 Update U.
e = 5 Median is 5 Terminate.