题目点击这里 ➡️「寻找两个正序数组的中位数」
思路(合并数组,寻找中位数):
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int[] nums = new int[nums1.length + nums2.length];
int index=0,l1=0,l2=0;
while (l1 < nums1.length && l2 < nums2.length) {
if (nums1[l1] <= nums2[l2]) {
nums[index] = nums1[l1];
l1 ++;
} else {
nums[index] = nums2[l2];
l2 ++;
}
index++;
}
if (l1 == nums1.length) {
for (;l2 < nums2.length; l2 ++, index ++) {
nums[index] = nums2[l2];
}
}
if (l2 == nums2.length) {
for (;l1 < nums1.length; l1 ++, index ++) {
nums[index] = nums1[l1];
}
}
if (nums.length % 2 != 0) {
return Double.valueOf(nums[nums.length / 2]);
}
return (nums[nums.length / 2] + nums[nums.length / 2 - 1]) / 2.0;
}
思路(二分法):
首先需要知道两个数组都是正序的,获得中位数就是两个数组中位置处于(m+n)/ 2 的那个数字,如果每次可以排除一些数字,最后剩下的就是想要获得的特定位置的数字;
假设给定两个数组A[m]、B[n],需要获得A、B两数组中第k小的数字「k=(m+n)/2」
如果我们取A[k/2]和B[k/2],则最多会有k+2个数字比这两个数字最小的大,导致无法排除不符合规则的数字,所以取A[k/2 - 1]和B[k/2 - 1] 来进行比较,若A[k/2 - 1] <= B[k/2 - 1],则A[0…k/2-1]都肯定不是正确结果,直接排出即可。
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1 = nums1.length, len2 = nums2.length;
int len = len1 + len2;
// 如果是奇数,返回对应位置的数
if (len % 2 == 1) {
return Double.valueOf(getKthNum(nums1, nums2, len / 2 + 1));
}
return (getKthNum(nums1, nums2, len / 2) + getKthNum(nums1, nums2, len / 2 + 1)) / 2.0;
}
// 获得第 k 小的数
private int getKthNum(int[] nums1, int[] nums2, int k) {
int len1 = nums1.length, len2 = nums2.length;
int i1 = 0, i2 = 0;
while (true) {
// 边界条件判断
if (i1 == len1) {
return nums2[i2 + k - 1];
}
if (i2 == len2) {
return nums1[i1 + k - 1];
}
// k = 1,取排出元素后两个数组第一个数的最小值
if (k == 1) {
return Math.min(nums1[i1], nums2[i2]);
}
// 考虑数组越界情况
int index1 = Math.min(k/2 + i1, len1) - 1, index2 = Math.min(k/2 + i2, len2) - 1;
if (nums1[index1] <= nums2[index2]) {
// 排除不符合条件的数字
k -= (index1 - i1 + 1);
i1 = index1 + 1;
} else {
k -= (index2 - i2 + 1);
i2 = index2 + 1;
}
}
}