版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mike_learns_to_rock/article/details/88809097
解法1 排序
- 假排序,只排到前一半的数即可。
- 时间复杂度:O(m + n)
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int l1 = nums1.length;
int l2 = nums2.length;
int total = l1 + l2;
int[] virtual = new int[total];
int n1 = 0;
int n2 = 0;
int index = 0;
while (n1 < l1 && n2 < l2 && index <= total/2) {
if (nums1[n1] < nums2[n2]) {
virtual[index] = nums1[n1];
n1++;
} else {
virtual[index] = nums2[n2];
n2++;
}
index++;
}
while (n1 < l1 && index <= total/2) {
virtual[index++] = nums1[n1++];
}
while (n2 < l2 && index <= total/2) {
virtual[index++] = nums2[n2++];
}
if ((total & 1) == 1 ) {
return virtual[total/2];
} else {
return (double)virtual[total/2 - 1] / 2 + (double)virtual[total/2] / 2;
}
}
解法2 分治
- 时间复杂度O(log(m+n))
- 转换为findKth问题,这里的K从0开始,表示offset
- A和B长度分别为m和n,比较A[k/2] 和 B[k/2]的大小(也可以比较A[m * k / (m + n)]和B[n * k / (m + n)])
- A[k/2] < B[k/2], 转换为从A[k/2 + 1, …] 和B数组寻找第k/2大的数
- A[k/2] > B[k/2],转换为从B[k/2 + 1, …] 和A数组寻找第k/2大的数
- A[k/2] == B[k/2],得到答案
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int total = nums1.length + nums2.length;
if (total % 2 == 0) {
return (double)findKth(nums1, 0, nums2, 0, total / 2 - 1) / 2 +
(double)findKth(nums1, 0, nums2, 0, total / 2) / 2;
} else {
return findKth(nums1, 0, nums2, 0, total / 2);
}
}
// k从0开始,第k小的数
private int findKth(int[] nums1, int start1, int[] nums2, int start2, int k) {
if (nums1.length - start1 > nums2.length - start2) {
return findKth(nums2, start2, nums1, start1, k);
}
if (nums1.length - 1 < start1) {
return nums2[start2 + k];
}
if (k == 0) {
return Math.min(nums1[start1], nums2[start2]);
}
// k1 + 1 + k2 + 1 == k + 1
int offset1 = 0;
if (k / 2 < nums1.length - 1 - start1) {
offset1 = k / 2;
} else {
offset1 = nums1.length - 1 - start1;
}
int offset2 = k - 1 - offset1;
if (nums1[offset1 + start1] < nums2[offset2 + start2]) {
return findKth(nums1, start1 + offset1 + 1, nums2, start2, k - offset1 - 1);
} else if (nums1[offset1 + start1] > nums2[offset2 + start2]) {
return findKth(nums1, start1, nums2, start2 + offset2 + 1, k - offset2 - 1);
} else {
return nums1[start1 + offset1];
}
}
解法3 二分查找
- 时间复杂度 O(log(m+n))
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
if (len1 > len2) return findMedianSortedArrays(nums2, nums1);
int k = (len1 + len2 + 1) / 2;
int l = 0;
int r = len1;
//find the m1 so that nums1[m1] >= nums2[m2 - 1]
while(l < r){
int m1 = l + (r - l) / 2;
int m2 = k - m1;
if (nums1[m1] < nums2[m2 - 1]){
l = m1 + 1;
} else {
r = m1;
}
}
int m1 = l;
int m2 = k - l;
int c1 = Math.max(m1 <= 0 ? Integer.MIN_VALUE : nums1[m1 - 1],
m2 <= 0? Integer.MIN_VALUE: nums2[m2 - 1]);
if ((len1 + len2) % 2 ==1) return c1;
int c2 = Math.min(m1 >= len1 ? Integer.MAX_VALUE : nums1[m1],
m2 >= len2 ? Integer.MAX_VALUE: nums2[m2]);
return (c1 + c2) / 2.0;
}