力扣4 寻找两个正序数的中位数
作者:互联网
力扣4 寻找两个正序数的中位数
二分杀我!
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//官方解答的核心就是两条线使两个数组分成四段,比较贴近两条线的那四个数(有可能是三个)
//官方解答没问题,但属实是吓唬人,其实说白了就是二分一下较小的数组。
//因为短的数组位置确定了,大的位置必定唯一
//为使得程序好写,当出现了小的越界了的情况,依然存在第四个数,设那个数为最小值或最大值。
//保证num1为最小的数组
if(nums1.length>nums2.length){
int[] temp = nums1;
nums1 = nums2;
nums2 = temp;
}
//求出总的左边个数(奇数偶数统一处理)
int n1 = nums1.length;
int n2 = nums2.length;
int total_left = (n1+n2+1)/2;
//算法本身:二分短的数组,该二分的终止条件为本题核心
//短数组的线恰好画对了的条件是:
// num1[mid-1]<=num2[long_mid]&&num1[mid]>=nums2[long_mid-1];(即 交叉也保序)
// 官方解答比较牛掰 判断一个条件即可,因为在二分的过程中,分到最后第二个条件必然满足了。
int left = 0;
int right = n1;
//这里的left和right 说明一下,前几天做二分心态崩了,导致我不做题了。
//这道题就解了当时的惑
// 我当时的理解是 left 可取0所以是表示下标;right是长度,所以表示是个数,这两个怎么能在一起出现呢?
//现在看来我真是煞笔,这里的定义不同,这里是线的取值范围,1到5 五个数,一共六个空。
while(left<right){
//若令mid为短数组的中间线位置右边的数的下标(mid恰好代表线左边的数有几个)
int mid = (left+right+1)/2;
//则长数组线左边必然有total_left-mid个,
int long_mid = total_left-mid;
if(nums1[mid-1]>nums2[long_mid]){//这里出现了[mid-1]需要担心数组越界,需要担心mid取0,但是mid取不到0。
//ps:如果数组长度就为1 是能取到0的 但可惜while条件都不满足,跳不进来。。。。程序压根走不到这。
//说明num1的线画的太靠右了
right = mid-1;
}else{
left = mid; //但凡是left=mid或者right=mid了都得考虑死循环。
}
}
//结局的left是我心心念念的线右边的数的下标。下面稍作处理返回即可。
//把那四个数找出来,对越界的情况稍作处理。使其依然能参与比较。
int line1_left = (left==0?(int)-1e7:nums1[left-1]);
int line1_right = (left==n1)?(int)1e7:nums1[left];
int line2_left = (total_left-left==0)?(int)-1e7:nums2[total_left-left-1];
int line2_right = (total_left-left==n2)?(int)1e7:nums2[total_left-left];
if((n1+n2)%2==1){
return (double)Math.max(line1_left,line2_left);
}
return (Math.max(line1_left,line2_left)+Math.min(line1_right,line2_right))/2f;
}
}
标签:right,int,mid,中位数,力扣,序数,nums1,nums2,left 来源: https://www.cnblogs.com/Rogy/p/15755363.html