美文网首页数据结构和算法分析
4. Median of Two Sorted Arrays

4. Median of Two Sorted Arrays

作者: Shiyi001 | 来源:发表于2016-10-23 08:40 被阅读0次

    <p><p>There are two sorted arrays <b>nums1</b> and <b>nums2</b> of size m and n respectively.</p>

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

    <p><b>Example 1:</b><br />
    <pre>
    nums1 = [1, 3]
    nums2 = [2]

    The median is 2.0
    </pre>
    </p>

    <p><b>Example 2:</b><br />
    <pre>
    nums1 = [1, 2]
    nums2 = [3, 4]

    The median is (2 + 3)/2 = 2.5
    </pre>
    </p></p>


    解题思路

    这道题的意思是求出两个已排序好的数列的中位数,也就是找到第<b>(m + n) / 2</b>的哪个数。(奇偶暂不讨论)

    现在的问题转化为如何在数列中找到第k大的数。

    寻找第k大的数

    如果只有一个数列,答案是显而易见的~

    现在有两个数列,我们能不能把两个数列简化为一个数列呢?答案是可以的,那就是分治

    怎么分治?

    分治的思想十分简单,就是把一个大问题不断地分解为若干个小问题,直到小问题能在线性时间内解决。治,在我们这里,就是两个数列变为了一个数列。

    那么怎么“分”呢?

    我们分别取两个数列的中位数,分别为a[mid]和b[mid] (不妨设a[mid] > b[mid]),他们前面分别有num1和num2个数。如果k大于num1+num2,那么说明我们要找的数不在最小的那部分,接下来我们要去a数列全段和b数列后半段去寻找;如果k小于num1+num2,那么说明我们要找的数不在最大的那部分,接下来我们要去a数列前段和b数列全段去寻找。这样做的时间复杂度为O(nlogn),只不过底数不是2,而是4/3。

    好了,现在我们可以在两个数列中寻找第k大的数了。接下来只要对奇偶分类,我们就可以很容易地求出两个数来中的中位数了~


    代码

    class Solution {
    public:
        double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
            int m = nums1.size(), n = nums2.size();
            double res;
            if ((m+n) % 2 == 0) {
                res = ((double)(findKth(nums1, 0, m-1, nums2, 0, n-1, (m + n) / 2)) + (double)(findKth(nums1, 0, m-1, nums2, 0, n-1, (m + n) / 2 +1))) / 2;
            } else {
                res = (double)(findKth(nums1, 0, m-1, nums2, 0, n-1, (m + n) / 2 + 1));
            }
            return res;
        }
    private:
        int findKth(vector<int>& nums1, int aL, int aR, vector<int>& nums2, int bL, int bR, int k) {
            //printf("aL=%d aR=%d bL=%d bR=%d k=%d\n", aL, aR, bL, bR, k);
    
            if (aL > aR) return nums2[bL + k - 1];
            if (bL > bR) return nums1[aL + k - 1];
            
            int aMid = (aR - aL) / 2 + aL;
            int bMid = (bR - bL) / 2 + bL;
    
            if (nums1[aMid] <= nums2[bMid]) {
                if (k <= (aMid - aL) + (bMid - bL) + 1) {
                    return findKth(nums1, aL, aR, nums2, bL, bMid - 1, k);
                } else {
                    return findKth(nums1, aMid + 1, aR, nums2, bL, bR, k - (aMid - aL + 1));
                }
            } else {
                if (k <= (aMid - aL) + (bMid - bL) + 1) {
                    return findKth(nums1, aL, aMid - 1, nums2, bL, bR, k);
                } else {
                    return findKth(nums1, aL, aR, nums2, bMid + 1, bR, k - (bMid - bL + 1));
                }
            }
            return 0;
        }
    };
    

    相关文章

      网友评论

        本文标题:4. Median of Two Sorted Arrays

        本文链接:https://www.haomeiwen.com/subject/wzahuttx.html