There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).算法
两个排序数组,找这两个排序数组的中位数,时间复杂度为O(log(m+n))数组
设数组A的长度为m, 数组B的长度为n, 两个数组都都是递增有序的。spa
求这两个数组的中位数.net
首先咱们看看中位数的特色,一个大小为n的数组,code
若是n是奇数,则中位数只有一个,数组中刚好有 (n-1)/2 个元素比中位数小。排序
若是n是偶数,则中位数有两个(下中位数和上中位数),这里咱们只求下中位数,对于下中位数,get
数组中刚好有(n-1)/2个元素比下中位数小。it
此题中,中位数只有一个,它前面有 c = (m+n-1)/2 个数比它小。中位数要么出如今数组A中,io
要么出如今数组B中,咱们先从数组A开始找。考察数组A中的一个元素A[p], 在数组A中,ast
有 p 个数比A[p]小,若是数组B中刚好有 c-p 个数比 A[p] 小, 则俩数组合并后就刚好有 c 个数比A[p]小,
因而A[p]就是要找的中位数。 以下图所示:
若是A[p] 刚好位于 B[c-p-1] 和 B[c-p] 之间,则 A[p] 是中位数
若是A[p] 小于 B[c-p-1] ,说明A[p] 过小了,接下来从 A[p+1] ~A[m-1]开始找
若是A[p] 大于 B[c-p] ,说明A[p] 太大了,接下来从 A[0] ~A[p-1]开始找。
若是数组A没找到,就从数组B找。
注意到数组A和数组B都是有序的,因此能够用二分查找。
采用类二分查找算法
public class Solution { /** * 004-Median of Two Sorted Arrays(两个排序数组的中位数) * * @param nums1 * @param nums2 * @return */ public double findMedianSortedArrays(int[] nums1, int[] nums2) { if (nums1 == null) { nums1 = new int[0]; } if (nums2 == null) { nums2 = new int[0]; } int len1 = nums1.length; int len2 = nums2.length; if (len1 < len2) { // 确保第一个数组比第二个数组长度大 return findMedianSortedArrays(nums2, nums1); } // 若是长度小的数组长度为0,就返回前一个数组的中位数 if (len2 == 0) { return (nums1[(len1 - 1) / 2] + nums1[len1 / 2]) / 2.0; } int lo = 0; int hi = len2 * 2; int mid1; int mid2; double l1; double l2; double r1; double r2; while (lo <= hi) { mid2 = (lo + hi) / 2; mid1 = len1 + len2 - mid2; l1 = (mid1 == 0) ? Integer.MIN_VALUE : nums1[(mid1 - 1) / 2]; l2 = (mid2 == 0) ? Integer.MIN_VALUE : nums2[(mid2 - 1) / 2]; r1 = (mid1 == len1 * 2) ? Integer.MAX_VALUE : nums1[mid1 / 2]; r2 = (mid2 == len2 * 2) ? Integer.MAX_VALUE : nums2[mid2 / 2]; if (l1 > r2) { lo = mid2 + 1; } else if (l2 > r1) { hi = mid2 - 1; } else { return (Math.max(l1, l2) + Math.min(r1, r2)) / 2; } } return -1; } }