[LeetCode] 4. Median of Two Sorted Arrays(想法题/求第k小的数)

传送门

Description

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

 

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

思路

题意:给定两个有序数组,在log级别的复杂度下,求得这两个数组中所有元素的中间值

题解:转换为求第k大的数。

假设A和B的元素个数都大于k/2,我们将A的第k/2个元素(即A[k/2-1])和B的第k/2个元素(即B[k/2-1])进行比较,有以下三种情况(为了简化这里先假设k为偶数,所得到的结论对于k是奇数也是成立的):

  • A[k/2-1] == B[k/2-1]
  • A[k/2-1] > B[k/2-1]
  • A[k/2-1] < B[k/2-1]

如果A[k/2-1] == B[k/2-1],意味着A[0]到A[k/2-1]的肯定在AB的top k元素的范围内,换句话说,A[k/2-1]不可能大于AB的第k大元素。

因此,我们可以放心的删除A数组的这k/2个元素。

同理,当A[k/2-1] > B[k/2-1]时,可以删除B数组的k/2个元素。

当A[k/2-1] == B[k/2-1]时,说明找到了第k大的元素,直接返回A[k/2-1]或B[k/2-1]即可。

因此,我们可以写一个递归函数。那么函数什么时候应该终止呢?

  • 当A或B是空时,直接返回B[k/2-1]或A[k/2-1];
  • 当k = 1时,返回min(A[0],B[0]);
  • 当A[k/2-1] ==B[k/2-1]时,返回A[k/2-1]或B[k/2-1]
 
C++:
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1 = nums1.size(),len2 = nums2.size();
        int len = len1 + len2;
        if (len & 1){
            return findKth(nums1,nums2,len / 2 + 1);
        } else{
            return (findKth(nums1,nums2,len / 2) + findKth(nums1,nums2,len / 2 + 1))/2;
        }
    }

    double findKth(vector<int> nums1,vector<int> nums2,int k){
        int len1 = nums1.size(),len2 = nums2.size();
        if (len1 > len2)    return findKth(nums2,nums1,k);
        if (len1 == 0)  return nums2[k - 1];
        if (k == 1)  return min(nums1[0],nums2[0]);
        int a = min(k / 2,len1),b = k - a;
        if (nums1[a - 1] < nums2[b - 1])  
            return findKth(vector<int>(nums1.begin() + a,nums1.end()),nums2,k - a);
        else if (nums1[a - 1] > nums2[b - 1])   
            return findKth(nums1,vector<int>(nums2.begin() + b,nums2.end()),k - b);
        else    return nums1[a - 1];
    } 
};

Java:

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len = nums1.length + nums2.length;
        if ((len  & 1) == 1){
            return findKth(nums1,nums2,len / 2 + 1);
        }
        else{
            return (findKth(nums1,nums2,len / 2) + findKth(nums1,nums2,len / 2 + 1)) / 2;
        }
    }

    public double findKth(int[] nums1, int[] nums2,int k){
        int len1 = nums1.length,len2 = nums2.length;
        if (len1 > len2)    return findKth(nums2,nums1,k);
        if (len1 == 0)   return nums2[k - 1];
        if (k == 1) return Math.min(nums1[0],nums2[0]);
        int a = Math.min(k / 2,len1),b = k - a;
        if (nums1[a - 1] < nums2[b - 1])   return findKth(Arrays.copyOfRange(nums1, a, len1),nums2,k - a);
        else    if (nums1[a - 1] > nums2[b - 1])    return findKth(nums1,Arrays.copyOfRange(nums2,b,len2), k - b);
        else    return nums1[a - 1];
    }
}
原文地址:https://www.cnblogs.com/ZhaoxiCheung/p/7342572.html