You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于二分查找左右索引的两个有序数组中位数求解疑问

两个有序数组合并后的中位数查找算法疑问

给定两个长度分别为l和m的有序数组A和B,合并后数组长度n=l+m,需求解合并数组的中位数。根据中位数定义,它大于一半元素且小于另一半元素。若A[i]是中位数,因A有序,A[i]≥A[0..i-1],同时需大于B中j=⌈n/2⌉-(i-1)个元素,即A[i]≥B[0..j-1]。若A[i]不是中位数,可通过A[i]与B[j]、B[j+1]的大小关系判断其与中位数的大小,进而进行二分查找。

相关伪代码如下:

MEDIAN-SEARCH(A[1 . . l], B[1 . . m], left,right)

if left > right:
  MEDIAN-SEARCH(B, A, max(1, ⌈n/2⌉ − l), min(m, ⌈n/2⌉))

i = ⌊(left + right)/2⌋

j = ⌈n/2⌉ - i

if (j = 0 or A[i] > B[j]) and (j = m or A[i] <= B[j + 1])
  return A[i]

else if (j = 0 or A[i] > B[j]) and j != m and A[i] > B[j + 1]
  return MEDIAN-SEARCH(A, B, left, i − 1)

else
  return MEDIAN-SEARCH(A, B, i + 1, right)

初始调用为:

MEDIAN-SEARCH(A[1..l], B[1..m], max(1, ⌈n/2⌉ − m), min(l, ⌈n/2⌉))

疑问1:初始调用中left和right取值的作用

初始调用里的left和right是给二分查找划定有效候选区间,直接排除掉A中不可能是中位数的位置,避免做无用功。

拆解一下两个值的逻辑:

  • ⌈n/2⌉是合并后数组里,中位数及之前的元素总个数(比如n=5时是3,前3个元素包含中位数;n=4时是2,对应中位数相关的计数逻辑)。
  • min(l, ⌈n/2⌉):就算B的所有元素都比A小,A里前⌈n/2⌉个元素才可能包含中位数,超过这个位置的元素肯定比中位数大,完全不用查。
  • max(1, ⌈n/2⌉ − m):如果B的所有元素都比A大,那A至少要拿出⌈n/2⌉ - m个元素,才能凑够合并数组前⌈n/2⌉个元素(B最多贡献m个)。所以A中比这个位置靠前的元素,肯定比中位数小,也不用查。

说白了,这俩值把A里可能是中位数的位置框死在一个小范围里,让二分查找从一开始就精准定位,减少递归次数。

疑问2:算法的时间复杂度是O(log(N))还是O(log(max(l,m)))?

严格来说,这个算法的时间复杂度是O(log(min(l,m))),但如果要在你给出的两个选项里选,它更接近O(log(max(l,m))),实际效率比O(log(N))更高。

原因是:每次递归都会把当前处理数组的查找范围减半;当其中一个数组的候选范围耗尽(left>right),算法会切换到另一个数组继续二分。最终的递归次数由两个数组中较短的那个长度决定——比如A长1000,B长10,切换后在B上最多递归4次(log₂(10)≈3.32),远小于log₂(1010)≈10(也就是O(log(N))的情况)。

如果两个数组长度接近,比如l=m,那log(min(l,m))=log(max(l,m))=log(N/2)≈log(N),这时候三个复杂度表述的差异可以忽略,但本质上还是由较短数组的长度主导。


内容的提问来源于stack exchange,提问作者Shashikant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:24:53