[译]两个排序数组的中值

简介: 原文地址: Median of Two Sorted Arrays有两个排序数组A和B大小分别为m和n。找到两个排序数组的中值。整个运行时复杂度应该是O(log(m + n))。

原文地址: Median of Two Sorted Arrays

有两个排序数组A和B大小分别为m和n。找到两个排序数组的中值。整个运行时复杂度应该是O(log(m + n))。

Java 解决方案1
这个问题可以转化为找到第k个元素的问题,k是(A的长度+ B的长度)/ 2。
如果两个数组中的任何一个都是空的,那么第k个元素就是非空数组的第k个元素。如果k == 0,第k个元素是A或B的第一个元素。
对于一般情况(所有其他情况),我们需要将指针移动到数组大小的一半以获得时间log(n)。


img_01edc23aa4e9e314960f70b79792f692.png
图1
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int total = nums1.length+nums2.length;
    if(total%2==0){
        return (findKth(total/2+1, nums1, nums2, 0, 0)+findKth(total/2, nums1, nums2, 0, 0))/2.0;
    }else{
        return findKth(total/2+1, nums1, nums2, 0, 0);
    }
}
 
public int findKth(int k, int[] nums1, int[] nums2, int s1, int s2){
    if(s1>=nums1.length)
        return nums2[s2+k-1];
 
    if(s2>=nums2.length)
        return nums1[s1+k-1];
 
    if(k==1)
        return Math.min(nums1[s1], nums2[s2]);
 
    int m1 = s1+k/2-1;
    int m2 = s2+k/2-1;
 
    int mid1 = m1<nums1.length?nums1[m1]:Integer.MAX_VALUE;    
    int mid2 = m2<nums2.length?nums2[m2]:Integer.MAX_VALUE;
 
    if(mid1<mid2){
        return findKth(k-k/2, nums1, nums2, m1+1, s2);
    }else{
        return findKth(k-k/2, nums1, nums2, s1, m2+1);
    }
}

时间是O(log(k)).

Java 解决方案2
实际上,我们可以用多种不同的方式来编写二进制搜索解决方案。下面是其中一个:

public static double findMedianSortedArrays(int A[], int B[]) {
    int m = A.length;
    int n = B.length;
 
    if ((m + n) % 2 != 0) // odd
        return (double) findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1);
    else { // even
        return (findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1) 
            + findKth(A, B, (m + n) / 2 - 1, 0, m - 1, 0, n - 1)) * 0.5;
    }
}
 
public static int findKth(int A[], int B[], int k, 
    int aStart, int aEnd, int bStart, int bEnd) {
 
    int aLen = aEnd - aStart + 1;
    int bLen = bEnd - bStart + 1;
 
    // Handle special cases
    if (aLen == 0)
        return B[bStart + k];
    if (bLen == 0)
        return A[aStart + k];
    if (k == 0)
        return A[aStart] < B[bStart] ? A[aStart] : B[bStart];
 
    int aMid = aLen * k / (aLen + bLen); // a's middle count
    int bMid = k - aMid - 1; // b's middle count
 
    // make aMid and bMid to be array index
    aMid = aMid + aStart;
    bMid = bMid + bStart;
 
    if (A[aMid] > B[bMid]) {
        k = k - (bMid - bStart + 1);
        aEnd = aMid;
        bStart = bMid + 1;
    } else {
        k = k - (aMid - aStart + 1);
        bEnd = bMid;
        aStart = aMid + 1;
    }
 
    return findKth(A, B, k, aStart, aEnd, bStart, bEnd);
}
目录
相关文章
|
算法
arr = [1,2,5,8,9,10,20,30,40] 有一个从小到大排序好的数组,现在输入一个数,要求按照原来的规律插入到数组中
arr = [1,2,5,8,9,10,20,30,40] 有一个从小到大排序好的数组,现在输入一个数,要求按照原来的规律插入到数组中
113 0
|
19天前
|
算法
正序数组中位数
给定两个有序数组nums1和nums2,要求找到它们合并后的中位数,时间复杂度需达到O(log(m+n))。通过双指针法遍历两个数组,使用left和right变量记录遍历过程中的值,最终根据合并后数组长度的奇偶性返回中位数。此方法有效避免了直接合并数组带来的高时间复杂度问题。
20 0
|
7月前
|
算法 C++
寻找两个正序数组的中位数(C++)
寻找两个正序数组的中位数(C++)
36 0
|
算法 测试技术 C++
C++算法:寻找两个正序数组的中位数
C++算法:寻找两个正序数组的中位数
寻找两个正序数组中的中位数
寻找两个正序数组中的中位数
每日三题-寻找两个正序数组的中位数 、搜索旋转排序数组、 在排序数组中查找元素的第一个和最后一个位置
每日三题-寻找两个正序数组的中位数 、搜索旋转排序数组、 在排序数组中查找元素的第一个和最后一个位置
58 2
每日三题-寻找两个正序数组的中位数 、搜索旋转排序数组、 在排序数组中查找元素的第一个和最后一个位置
|
Rust 算法 Java
寻找两个正序数组的中位数
寻找两个正序数组的中位数
130 0
|
算法
算法练习——(8)用下标排序
问题:给你n个无序的int整型数组arr,并且这些整数的取值范围都在0-20之间,要你在 O(n) 的时间复杂度中把这 n 个数按照从小到大的顺序打印出来。
数组奇数排序
数组奇数排序
87 0