伴你如风、护你如影|

xzh-yyds

园龄:3年9个月粉丝:0关注:2

leetcode4-寻找两个正序数组的中位数

寻找两个正序数组的中位数

  • 二分查找
class Solution {
    int len1, len2;
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        len1 = nums1.length; len2 = nums2.length;
        int total = len1+len2, mid = total / 2;
        // 需要从0开始移动k位得到答案,而不是返回数组中第k位的数字,所以要+1
        if(total % 2 == 0)
            return (getKth(nums1, nums2, mid) + getKth(nums1, nums2, mid+1))/2.0;
        else
            return getKth(nums1, nums2, mid+1);
    }
    public int getKth(int[] nums1, int[] nums2, int k){
        int l = 0, r = 0;
        while(true){
            // 当l == len1时,意味着左数组遍历完毕,返回右数组相应的位数。
            // 这里对l和r进行处理就是为了保证l和r指针都指向相应的位置,不会使得第三个if语句段错误
            if(l == len1)   return nums2[r+k-1];
            // 同上
            if(r == len2)   return nums1[l+k-1];
            // 当k == 1时,意味着得到下一个数字,那么这个数字就是两个指针的较小值
            if(k == 1)  return Math.min(nums1[l], nums2[r]);
            int half = k / 2;
            // 移动相应的位数,最后-1是为了对应数组的位置
            int newIndex1 = Math.min(len1, l+half)-1, newIndex2 = Math.min(len2, r+half)-1;
            if(nums1[newIndex1] < nums2[newIndex2]){
                // k减去已经移动的位数,由于l向右移动(newIndex1-l+1)位,变成newIndex1+1
                k -= newIndex1-l+1;
                l = newIndex1+1;
            }else{
                k -= newIndex2-r+1;
                r = newIndex2+1;
            }
        }
    }
}
  • 切分数组
class Solution {
    public double findMedianSortedArrays(int[] A, int[] B) {
        int m = A.length;
        int n = B.length;
        if (m > n) { 
            return findMedianSortedArrays(B, A); // 保证 m <= n
        }
        int iMin = 0, iMax = m;
        while (iMin <= iMax) {
            int i = (iMin + iMax) / 2;
            int j = (m + n + 1) / 2 - i;
            if (j != 0 && i != m && B[j-1] > A[i]){ // i 需要增大
                iMin = i + 1; 
            }
            else if (i != 0 && j != n && A[i-1] > B[j]) { // i 需要减小
                iMax = i - 1; 
            }
            else { // 达到要求,并且将边界条件列出来单独考虑
                int maxLeft = 0;
                if (i == 0) { maxLeft = B[j-1]; }
                else if (j == 0) { maxLeft = A[i-1]; }
                else { maxLeft = Math.max(A[i-1], B[j-1]); }
                if ( (m + n) % 2 == 1 ) { return maxLeft; } // 奇数的话不需要考虑右半部分

                int minRight = 0;
                if (i == m) { minRight = B[j]; }
                else if (j == n) { minRight = A[i]; }
                else { minRight = Math.min(B[j], A[i]); }

                return (maxLeft + minRight) / 2.0; //如果是偶数的话返回结果
            }
        }
        return 0.0;
    }
}

本文作者:xzh-yyds

本文链接:https://www.cnblogs.com/xzh-yyds/p/16586234.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xzh-yyds  阅读(22)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开