LeetCode4 Median of Two Sorted Arrays分治法求两数组的中位数

分治法寻找两个有序数组的中位数

题意

给定两个大小为 m 和 n 的有序数组A 和 B。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
保证A 和 B 不会同时为空。

样例1

A = [1, 3]
B= [2]

中位数是 2.0

样例2

A = [1, 2]
B = [3, 4]

中位数是 (2 + 3)/2 = 2.5

单个数组

我们先简化问题,如何求出单个数组的中位数?

A[0] A[1] A[m-1]

对于一个数组可以选择两个位置进行分割,使得两边元素个数相等。对于任意偶数个元素必有如下表所示的分割使得两边元素个数相等。

left mid right
A[0], A[1], …,A[i-2] A[i-1] , A[i] A[i+1], …, A[m-1]

同样,对于任意奇数个元素必有如下图所示的分割。

left mid right
A[0], A[1], …,A[i-1] A[i] A[i+1], …, A[m-1]
偶数个元素分割示例:
1 2 4 5 6 7 8 10
left mid right
1 , 2, 4 5, 6 7, 8, 10

中位数是(5 + 6)/2 = 5.5

奇数个元素分割示例:
1 2 3 4 5 6 7 8 9
left mid right
1 , 2, 3, 4 5 6, 7, 8, 9

中位数是5

两个等长数组

接下来将单个数组拆分成两个长度相等的数组。我们可以在A中确定位置i,B中确定位置j,使得左右两侧元素个数相等。1

left mid right
A[0], A[1], …, A[i-2] A[i-1], A[i] A[i+1], …, A[n-1]
B[0], B[1], …, B[j-2] B[j-1], B[j] B[j+1], …, B[n-1]
left mid right
A[0], A[1], …, A[i-1] A[i] A[i+1], …, A[n-1]
B[0], B[1], …, B[j-1] B[j] B[j+1], …, B[n-1]

我们选取偶数个元素的情况进行说明,奇数个元素与此类似,只需要在计算中位数的函数部分稍加改动。2

此时一定有

  • (i-1)-0+1+(j-1)-0+1 =(n-1)-i+1+(n-1)-j+1 => i + j = n - i + n - j
  • B[j-1] <= A[i] && A[i-1] <= B[j]

我们就可以通过这四个数字得到中位数了。可是我们如何找到i,j呢?

由于A、B长度一定,故只要确定i的位置,j的位置可以随之确定

  1. 分别计算两个数组的中位数;
  2. 若midA = midB ,则midA就是整个数组的中位数(思考一下为什么),返回midA;
  3. 若midA < midB, 则中位数一定出现在数组B的左半部分和数组A的右半部分。
    保留A |_ (n-1)/2 | ,…, A[n-1],将新得到的数组作为A;
    保留B [0], B[1], …, B[ n- |
    (n-1)/2 _| ]),将新得到的数组作为B;
  4. 若midA > midB, 则中位数一定出现在数组A的左半部分和数组B的右半部分。
    保留A [0], A[1], … A[n-|_ (n-1)/2 |],将新得到的数组作为A;
    保留B|
    (n-1)/2 _ | … B[n-1],将新得到的数组作为B;

(n-1)/2向下取整,这样能把参与中位数计算的较小的数保留下来;
n - | _ (n-1)/2 _|向上取整,这样能把参与中位数计算的较大的数保留下来。

  1. 直到B[j-1] <= A[i] && A[i-1] <= B[j],返回average(max(A[i-1], B[j-1]) + min(A[i], B[j])) / 2。
array 1 2 3 4
A 1 5 6 10
B 2 4 8 8

midA = (5 + 6) / 2 = 5.5 , midB = (4 + 8) / 2 = 6
midA < midB,取B的左半部分和A的右半部分

array 1 2 3 4
A * 5 6 10
B 2 4 8 *

mid = (5 + 6) / 2 = 5.5。

可以参考一下geeksforgeeks Median of two sorted arrays of same size这篇文章给出的的代码。

// A divide and conquer based  
// efficient solution to find  
// median of two sorted arrays  
// of same size. 
#include<bits/stdc++.h> 
using namespace std; 
  
/* to get median of a 
   sorted array */
int median(int [], int);  
  
/* This function returns median  
   of ar1[] and ar2[]. 
Assumptions in this function: 
    Both ar1[] and ar2[] are  
    sorted arrays 
    Both have n elements */
int getMedian(int ar1[],  
           
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值