首页 > 其他分享 >leetcode4-寻找两个正序数组的中位数

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

时间:2022-08-15 10:44:41浏览次数:78  
标签:leetcode4 正序 int 中位数 maxLeft else return nums1 nums2

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

  • 二分查找
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;
    }
}

标签:leetcode4,正序,int,中位数,maxLeft,else,return,nums1,nums2
From: https://www.cnblogs.com/xzh-yyds/p/16586234.html

相关文章

  • 4.寻找两个有序数组的中位数
    首先这个题目最容易想到的解决方法是把两个数组合并之后选出中位数,但是这样的时间复杂度为\(O(m+n)\)与题目的要求不符合,根据题目中的要求\(O(log(m+n))\)可以想到可能要采......
  • leetcode438_找到字符串中所有字母异位词
    438.找到字符串中所有字母异位词方法一:简单滑动窗口满足异位词条件:(1)s中子串s'与目标字符串p的长度相等(2)s'与p中字母相同(对排列方式没有要求)算法思路:在字符串s中构......