leetcode4. 寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
思路:
代码如下:
代码一:
package medium;
public class Leetcode4 {
public static void main(String[] args) {
int[] nums1=new int[]{1,3};
int[] nums2=new int[]{2,4};
double arrays = findMedianSortedArrays(nums1, nums2);
System.out.println(arrays);
}
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
if(nums1.length> nums2.length){
int [] temp=nums1;
nums1=nums2;
nums2=temp;
}
int m= nums1.length;
int n= nums2.length;
//分割线左边的所有元素需要满足的个数m+(n-m+1)/2
int totalLeft=(m+n+1)/2;
/*在nums1的区间[0,m]里查找恰当的分割线,
使得nums1[i - 1] <= nums2[j] && nums2[j - 1] <= nums1[i]*/
int left=0;
int right=m;
while (left<right){
int i=left+(right-left+1)/2;
int j=totalLeft-i;
if (nums1[i-1]>nums2[j]){
//下一轮搜索区间[left,i-1]
right=i-1;
}else {
//下一轮搜索区间[i,right]
left=i;
}
}
int i=left;
int j=totalLeft-i;
int nums1LeftMax=i==0?Integer.MIN_VALUE:nums1[i-1];
int nums1RightMin=i==m?Integer.MAX_VALUE:nums1[i];
int nums2LeftMax=j==0?Integer.MIN_VALUE:nums2[j-1];
int nums2RightMin=j==n?Integer.MAX_VALUE:nums2[j];
if (((m+n)%2)==1){
return Math.max(nums1LeftMax,nums2LeftMax);
}else {
return (double) ((Math.max(nums1LeftMax,nums2LeftMax)+Math.min(nums1RightMin,nums2RightMin)))/2;
}
}
}
代码二:
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
if(nums1.length> nums2.length){
int [] temp=nums1;
nums1=nums2;
nums2=temp;
}
int m= nums1.length;
int n= nums2.length;
//分割线左边的所有元素需要满足的个数m+(n-m+1)/2
int totalLeft=(m+n+1)/2;
/*在nums1的区间[0,m]里查找恰当的分割线,
使得nums1[i - 1] <= nums2[j] && nums2[j - 1] <= nums1[i]*/
int left=0;
int right=m;
while (left<right){
int i=left+(right-left)/2;
int j=totalLeft-i;
if (nums2[j-1]>nums1[i]){
//下一轮搜索区间[i+1,right]
left=i+1;
}else {
//下一轮搜索区间[left,i]
right=i;
}
}
int i=left;
int j=totalLeft-i;
int nums1LeftMax=i==0?Integer.MIN_VALUE:nums1[i-1];
int nums1RightMin=i==m?Integer.MAX_VALUE:nums1[i];
int nums2LeftMax=j==0?Integer.MIN_VALUE:nums2[j-1];
int nums2RightMin=j==n?Integer.MAX_VALUE:nums2[j];
if (((m+n)%2)==1){
return Math.max(nums1LeftMax,nums2LeftMax);
}else {
return (double) ((Math.max(nums1LeftMax,nums2LeftMax)+Math.min(nums1RightMin,nums2RightMin)))/2;
}
}