leetcode 4 Median of Two Sorted Arrays

题目描述

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)).
You may assume nums1 and nums2 cannot be both empty.

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

中位数

对于 A[1, 2, ..., n]
如果 n 为奇数, (n+1)/2 是中位数, 如 9, (9+1)=5
如果 n 为偶数, (n+1)/2 是下中位数, 如 10, (10+1)/2=5

两个有序数组的第 k 小的数

总体思路: 找到并排除掉 k-1 个比第 kth 小的数

给予两个有序数组 A, B

\(A[1, 2, \cdots, n]\)
\(B[1, 2, \cdots, m]\)

为了找到第 k 个大小的数, 我们可以利用两个数组的有序特性, 排除掉 \(\left\lfloor \frac{k}{2} \right\rfloor\) 个非解空间中的数(即排除掉 \(\left\lfloor \frac{k}{2} \right\rfloor\) 个小于第 kth 小的数), 方法如下:

\(A[1,\cdots, \frac{k}{2}] \quad | \quad A[\frac{k}{2} + 1, \cdots, n]\)
\(B[1,\cdots, \frac{k}{2}] \quad | \quad B[\frac{k}{2} + 1, \cdots, m]\)

如果 \(A[\frac{k}{2}]\space \gt \space B[\frac{k}{2}]\), 那么 \(B[\frac{k}{2}]\) 最大只可能比 \(A[1,\cdots, \frac{k}{2}-1]+B[1,\cdots, \frac{k}{2}-1] 大,\)

即: \(B[\frac{k}{2}]\) 最大为第 \(\frac{k}{2}-1+\frac{k}{2}-1 + 1 = k-1\) 大的数
故: \(B[1,\cdots, \frac{k}{2}]\) 一定比第 k 小的数小, 可以排除

接下来只需要在 \(A[1, 2, \cdots, n] 和 B[\frac{k}{2} + 1, \cdots, m]\) 寻找 \(k - \left\lfloor \frac{k}{2} \right\rfloor\) 小的数就好了

依照上面的思路:

  1. 如果两个数组合并的数组大小为奇数, 我们就是寻找第 \(\frac{n+m+1}{2}\) 小的数;
  2. 如果两个数组合并的数组大小为偶数, 我们就是寻找第 \(\frac{n+m+1}{2}\) 小和第 \(\frac{n+m+1}{2}+1\)小的数的平均数;

Solution

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len = nums1.size() + nums2.size();
        int mid = (len+1)/2;
        double median = kth(nums1, nums2, 0, 0, mid);
        // 找第 k 个大小的值的起始值就是从 1 开始
        // 所以中位数也是按照从 1 开始的计算
        
        if (len%2 == 0) {
            median = (median + kth(nums1, nums2, 0, 0, mid+1))/2.0;
        }
        return median;
    }
    
    int kth(vector<int>& nums1, vector<int>& nums2, int s1, int s2, int k) {
        int len1 = nums1.size();
        int len2 = nums2.size();
        
        if (s1 == len1) return nums2[s2+k-1];
        if (s2 == len2) return nums1[s1+k-1];
        if (k == 1) return min(nums1[s1], nums2[s2]);
        
        int step1 = min(k/2, len1-s1);
        int step2 = min(k/2, len2-s2);
        
        if (nums1[s1+step1-1] > nums2[s2+step2-1]) {
            return kth(nums1, nums2, s1, s2+step2, k-step2);
        }
        return kth(nums1, nums2, s1+step1, s2, k-step1);
    }
};
posted @ 2018-07-29 19:51  nowgood  阅读(219)  评论(0)    收藏  举报