Algorithm 在未排序的只读数组中查找中值
给定一个包含Algorithm 在未排序的只读数组中查找中值,algorithm,time-complexity,median,space-complexity,Algorithm,Time Complexity,Median,Space Complexity,给定一个包含n个元素的只读数组,用O(logn)空间和平均时间O(nlogn)查找数组中的中位数(大小为上限(n/2)-th个元素) 数组中的元素不同 数组未排序 不能更改数组中的任何值,只能读取它们 我曾考虑过使用快速排序的思想,但如果不更改数组,就不可能执行它。复制到另一个数组将超出所需的空间。您可以使用分治方法解决该问题,在最小值和最大值之间找到一个随机元素,检查它是否为中间值,中间值是否低于或高于它,并仅在数组的子范围上将问题缩小 将min设置为数组中的最小元素,将max设置为最大元
n个元素的只读数组,用O(logn)
空间和平均时间O(nlogn)
查找数组中的中位数(大小为上限(n/2)
-th个元素)
- 数组中的元素不同
- 数组未排序
- 不能更改数组中的任何值,只能读取它们
我曾考虑过使用快速排序的思想,但如果不更改数组,就不可能执行它。复制到另一个数组将超出所需的空间。您可以使用分治方法解决该问题,在最小值和最大值之间找到一个随机元素,检查它是否为中间值,中间值是否低于或高于它,并仅在数组的子范围上将问题缩小
将min
设置为数组中的最小元素,将max
设置为最大元素
在范围内选择一个随机数mid
(min
),如果没有这样的mid
,则min
或max
为中间值,找到中间值,然后完成操作
检查min
、mid
或max
是否为中位数(线性搜索,计算大小)
3.1。如果是这样,你就完了
3.2。否则,中位数介于(最小值,中间值)
或(中间值,最大值)
之间,并且您知道在哪里(如果更多值高于中间值或低于中间值)
3.3。如果它在(最小,中间)
,则设置max=mid
,否则,设置min=mid
3.4。返回到2
正确性:
- 如果算法找到一个数字,那么stop子句只是因为找到了中间值
- 对于每次迭代,中值仍然在
(min,max)
(带归纳法的形式证明…),并且范围保证在每次迭代中缩小,因此算法保证停止并产生一些结果
时间复杂性:
- 步骤1:仅重复一次,并花费
O(n)
时间
- 步骤2:花费
O(n)
时间(查找范围内的不同数字)并重复每次迭代
- 步骤3:花费
O(n)
时间(通过每个范围是线性的)
平均情况下有O(logn)
迭代(类似于二进制搜索推理)
这给了我们时间复杂度O(nlogn)
空间复杂性:
依赖于实现,但使用尾部递归(类似于上面的高级伪代码)实际上可以是O(1)
。对于正则递归,这是堆栈的O(logn)
。这里是一个简单的算法。它包括通过跟踪中位数所在区间的上下限来搜索中位数
设E为元素列表。将中值的上下限L和U设置为null
对于e中的每个元素e
如果L不为空且eU,e不能为中间值,则跳到下一个元素
扫描E并计算E之前元素的数量B,以及E之后元素的数量A
如果A=B,e为中间值,则终止。如果A=B+1,则没有单个中间值,但e在中间值点之前终止。如果B=A+1,则不存在单个中间值,但e在中间值点之后立即终止
如果A>B,中位数在e之后,设置L=e。如果B>A,则中值在e之前,设置U=e
空间复杂度为O(1)。平均时间复杂度最多为O(n2)和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.
我不知道你的意思,但我必须将所有元素插入到两个堆中,这将需要O(n)spaceVoting才能重新打开正如目前所写的,很难准确说出你在问什么,问题陈述非常清楚。OP展示了他的两种方法,并解释了它们失败的原因(展示了自我研究)。如果其中一位投票人能解释他们的重新投票,我会很高兴的。@amit我正要问同样的问题,我想要一个算法,在给定的数组中找到中间值而不改变,我想知道他们为什么要结束这个问题!!谢谢你的回答。您能再解释一下为什么堆栈的内存中需要另一个O(logn)@Robert此解决方案需要O(1)
额外的内存,但如果您将其移动到递归调用,而不将其优化为尾部递归,则会有O(logn)
递归调用,每个调用都会将一些变量推送到调用堆栈,从而为您提供O(logn)
space。这似乎是amit提出的算法的一个更难阅读的版本,20多分钟后发布。@tucuxi好吧,也许吧,但它更详细。amit只给出了高层次的步骤。我建议的算法可能更容易实现。