Median of Two Sorted Arrays

题目大意:在两个已经排好序的数组里面,找出这两个数组的中位数。

解题思路:求两个排好序的数组的中位数,可以用二分法来处理。

如果两个数组的长度(m + n)总和是奇数,则求第(m+n) / 2 + 1大的数

如果两个数组长度(m + n)总和是偶数,则求第(m+n) / 2和第(m+n)/2 + 1这两个数的平均值。

问题可以转换为求这两个已排序数组的第k大的数。


假设这两个数组为A[m]和B[n]

如果A[m/2] 大于等于 B[n/2]

如果 A[0] 到 A[m/2 - 1] 的长度与 B[0] 到 B[n/2]的长度和大于等于k

那么这个第k大的数必然在A[0] 到 A[m/2 - 1] 和B[0] 到 B[n/2]的这两个范围内,

所以A的范围可以缩小为求A[0]到A[m/2 -1] 和B[0]到B[n/2] 这两个数组第k大的数

如果 A[0] 到 A[m/2 - 1] 的长度与 B[0] 到 B[n/2]的长度小于k

那么可以去除B的0~ n/ 2范围的数, 求A的0~m 和 B的n/2 + 1~ n的第k - (n/2 + 1)大的数


如果A[m/2]小于B[n/2],分析的情况只是A与B交换下


范围一直缩小下去。

直到当B的长度为0时,返回A[k]

A的长度为0时,返回B[k]

k为1时,返回当前范围内A和B的首个最小的数。


#include <iostream>
#include <cstdio>
using namespace std;

class Solution {
	public:
		double findMedianSortedArrays(int A[], int m, int B[], int n) {
			if(((m + n) & 1) == 1)
			  return findKth(A, m, B, n, ((m + n) >> 1) + 1);
			else
			  return (findKth(A, m, B, n, ((m + n) >> 1) + 1) + findKth(A, m, B, n, ((m + n) >> 1))) / 2.0;
		}

	private:
		double findKth(int A[], int m, int B[], int n, int k) {
			int median_len = ((m + n) >> 1) + 1;
	
			int A_low = 0, A_high = m - 1;
			int B_low = 0, B_high = n - 1;
			while(A_low <= A_high && B_low <= B_high && k > 1){
				int A_median_index = (A_low + A_high) >> 1;
				int B_median_index = (B_low + B_high) >> 1;
				int A_median_len = A_median_index - A_low + 1;
				int B_median_len = B_median_index - B_low + 1;
		
				if(A[A_median_index] >= B[B_median_index]) {
					if(A_median_len + B_median_len - 1 >= k) {
						A_high = A_median_index - 1;
					} else {
						k -= B_median_len;
						B_low = B_median_index + 1;
					}
				} else {
					if(A_median_len + B_median_len - 1 >= k) {
						B_high = B_median_index -1;
					} else {
						k -= A_median_len;
						A_low = A_median_index + 1;
					}
				}
			}

			if(A_low > A_high) {
				return B[B_low + k - 1];
			} else if(B_low > B_high) {
				return A[A_low + k - 1];
			} else {
				return min(A[A_low], B[B_low]);
			} 		
		}
};




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值