给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
本题运用到了二分法进行中位数的查找,原因在于两个数组都是有序的,那么就需要找到一条分割线,使得分割线左侧的数据都小于分割线右侧的数据。同时左侧数据的总数要求不变,因为两个数组的长度已知,所以总数也是已知的,这样的话,我们对于第一个数组进行分割线的查找,同时通过这个分割线来确定第二个数组的分割线,确定的依据,便是第一个数组分割线左侧的数据刚刚小于第二个数组分割线右侧的数据。最终通过判断两个数组数据总数的奇偶性来进行相应的后续数据处理。
代码如下:
package 第四题;
import java.util.Scanner;
public class first {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] numsA = in.nextLine().split(" ");
String[] numsB = in.nextLine().split(" ");
int[] nums1 = new int[numsA.length], nums2 = new int[numsB.length];
for (int i = 0; i < numsA.length; i++) {
nums1[i] = Integer.parseInt(numsA[i]);
}
for (int i = 0; i < numsB.length; i++) {
nums2[i] = Integer.parseInt(numsB[i]);
}
if (nums1.length > nums2.length) {
int[] temp = nums1;
nums1 = nums2;
nums2 = temp;
}
int m = nums1.length, n = nums2.length;
int flag = m + (n - m + 1) / 2;
int left = 0;
int right = m;
while (left < right) {
int i = left + (right - left + 1) / 2;
int j = flag - i;
if (nums1[i - 1] > nums2[j]) {
right = i - 1;
} else {
left = i;
}
}
int i = left;
int j = flag - left;
int nums1left = i == 0 ? Integer.MIN_VALUE : nums1[i - 1];
int nums1right = i == m ? Integer.MAX_VALUE : nums1[i];
int nums2left = j == 0 ? Integer.MIN_VALUE : nums2[j - 1];
int nums2right = j == n ? Integer.MAX_VALUE : nums2[j];
if ((m + n) % 2 != 0) {
System.out.println(Math.max(nums1left, nums2left));
} else {
System.out.println(((double) (Math.max(nums1left, nums2left) + Math.min(nums1right, nums2right))) / 2);
}
}
// 以下为正式提交的代码
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
int[] temp;
temp = nums1;
nums1 = nums2;
nums2 = temp;
}
int m = nums1.length;
int n = nums2.length;
int flag = m + (n - m + 1) / 2;
int left = 0;
int right = m;
while (left < right) {
int i = (left + right + 1) / 2;
int j = flag - i;
if (nums1[i - 1] > nums2[j]) {
right = i - 1;
} else {
left = i;
}
}
int i = left;
int j = flag - left;
int nums1left = i == 0 ? Integer.MIN_VALUE : nums1[i - 1];
int nums1right = i == m ? Integer.MAX_VALUE : nums1[i];
int nums2left = j == 0 ? Integer.MIN_VALUE : nums2[j - 1];
int nums2right = j == n ? Integer.MAX_VALUE : nums2[j];
if ((m + n) % 2 != 0) {
return Math.max(nums1left, nums2left);
} else {
return ((double) (Math.max(nums1left, nums2left) + Math.min(nums1right, nums2right))) / 2;
}
}
}



