4. Median of Two Sorted Arrays
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)).
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
在两个排序的数组查找中位数,
使用归并,会超时。
// 时间复杂度O(N)) 空间复杂度O(1),归并超时
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1 == null || nums2 == null)
return 0.0;
int pa = 0;
int pb = 0;
int m = nums1.length;
int n = nums2.length;
int[] ans = new int[m + n];
int idx = 0;
while (pa < m || pb < n) {
if (pa == m) {
ans[idx++] = nums2[pb++];
continue;
}
if (pb == n) {
ans[idx++] = nums1[pa++];
continue;
}
if (nums1[pa] < nums2[pb])
ans[idx++] = nums1[pa++];
else
ans[idx++] = nums2[pb++];
}
if (((n + m) & 1) == 1)
return ans[idx / 2];
else
// 下标从0开始
return (ans[(n + m) / 2 - 1] + ans[(n + m) / 2]) / 2.0;
}
参考归并排序原理及其实现
二分查找思想,将a数组的中间元素与b数组的“中间元素”相比较,从而删掉较小元素所在数组的前一半和较大元素所在数组的后一半。递归下去
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int N = nums1.length + nums2.length;
if (N % 2 == 1)
return findKth(nums1, 0, nums2, 0, N / 2 + 1);
else
return (findKth(nums1, 0, nums2, 0, N / 2 + 1) + findKth(nums1, 0, nums2, 0, N / 2)) / 2.0;
}
// 返回第k大的元素,从1开始。
private int findKth(int[] a, int alo, int[] b, int blo, int k) {
// a数组为空时,返回b数组第k个元素
// k从1开始
// alo,blo是第一个元素
if (alo >= a.length)
return b[blo + k - 1];
// b数组为空时,返回a数组第k个元素
if (blo >= b.length)
return a[alo + k - 1];
// 当k==1时,返回a[alo]、b[alo]中小的那个
if (k == 1)
return Math.min(a[alo], b[blo]);
// i表示mid到lo之间的差值
int i = k / 2 - 1;
int aMid = Integer.MAX_VALUE;
int bMid = Integer.MAX_VALUE;
// lo+i正好为中位数下标位置
if (alo + i < a.length)
aMid = a[alo + i];
if (blo + i < b.length)
bMid = b[blo + i];
if (aMid < bMid)
// 在amid之前,包括amid,不可能存在中位数,跳过查找(删除),
// alo到amid(包括)之间有i+1个数字
// 去掉i+1个数字,原来第k大,变成第k-(i+1)大
return findKth(a, alo + i + 1, b, blo, k - i - 1);
else
return findKth(a, alo, b, blo + i + 1, k - i - 1);
}