class Solution {
/**
递归O(log(N+M))
(m + n) / 2就是要求的第k个数就是中位数x
假设, m, n >= k / 2,先从nums1和nums2各去前面k / 2个元素,
1. 如果nums1[k/2] < nums2[k/2], nums1[0..k/2]个数肯定小于中位数,不存在第k个数,删除掉。
剩下 nums1[k/2+1, n] nums2[0..m];
2.如果nums1[k/2] > nums2[k/2], 同理nums2[0..k/2]个数肯定小于中位数,不存在第k个数,删除掉;
3.如果nums1[k/2] == nums2[k/2],恰好相等,就是第k个数,根据奇偶个数返回中位数
*/
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums1.length, m = nums2.length;
//解决奇偶个数问题
int left = (n + m + 1) / 2;
int right = (n + m + 2) / 2;
return (getK(nums1, 0, nums2, 0, left) + getK(nums1, 0, nums2, 0, right)) /2.;
}
//A短 B长
private int getK(int[] A, int i, int[] B, int j, int k) {
if(A.length - i > B.length - j) return getK(B, j, A, i, k);
if(k == 1) {
if(i == A.length) return B[j];
else return Math.min(A[i], B[j]);
}
if(i == A.length) return B[j + k - 1];
int si = Math.min(A.length, i + k / 2), sj = j + k - k / 2;
if(A[si - 1] > B[sj - 1]) {
return getK(A, i, B, sj, k - (sj - j));
}else {
return getK(A, si, B, j, k - (si - i));
}
}
private int getK2(int[] A, int aStart, int[] B, int bStart, int k) {
if(aStart > A.length - 1) return B[bStart + k - 1];
if(bStart > B.length - 1) return A[aStart + k - 1];
if(k == 1) return Math.min(A[aStart], B[bStart]);
int aMin = (aStart + k / 2 - 1 < A.length)? A[aStart + k / 2 - 1] : Integer.MAX_VALUE;
int bMin = (bStart + k / 2 - 1 < B.length)? B[bStart + k / 2 - 1] : Integer.MAX_VALUE;
if(aMin < bMin) {
//去掉aStart..aStart+ k / 2 - 1数
return getK(A, aStart + k / 2, B, bStart, k - k / 2);
}else {
//去掉 bStart..bStart + k / 2 - 1数
return getK(A, aStart, B, bStart + k / 2, k - k / 2);
}
}
}
4.寻找两个正序数组的中位数
于 2018-08-15 01:23:50 首次发布