Leetcode - 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)).

[分析] 暴力法是简单的,合并后返回中位数。优化的方法是参考 http://blog.csdn.net/yutianzuijin/article/details/11499917介绍的解法,awesome! 思路的关键点是将原问题转为寻找两排序数组中第 k 小的数,中位数即为第 (n + m) / 2 小的数, n和m分别为输入中A 和 B 两个数组的长度。
findKth 思路:假设A 和 B长度均不小于 k/2, 比较A[k/2 - 1] 和 B[k/2 - 1]:
(1) A[k/2 - 1] < B[k/2 - 1]
则A的前 k/2个元素是AB合并后的前 k - 1 小的元素中,也即 A[k/2 - 1]不可能是要找的第k个数。反证法证明推断:假设A[k/2 - 1] 在AB合并后出现在第k个元素或以后位置,不妨设就是第k个元素,则 B[k/2 - 1]至少为第 k+1个元素。因为 小于 A[k/2 - 1]至多有 (k/2 - 1) * 2 = k -2 个元素,这与A[k/2 - 1]是合并后第 k个数矛盾,得证。
(2) A[k/2 - 1] > B[k/2 - 1]
分析同(1)。
(3) A[k/2 - 1] = B[k/2 - 1]
则A[k/2 - 1] 就是合并后第 k 个数。
findKth 每次缩小一半规模,时间复杂度是 logk, 因此找寻中位数时间复杂度为 log((m + n) / 2)。

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int total = nums1.length + nums2.length;
        if ((total & 1) == 0)
            return (findKth(nums1, nums2, 0, 0, total / 2) + findKth(nums1, nums2, 0, 0, total / 2 + 1)) * 1.0 / 2;
        else
            return findKth(nums1, nums2, 0, 0, total / 2 + 1);
    }
    public int findKth(int[] nums1, int[] nums2, int off1, int off2, int k) {
        if (nums1 == null || nums1.length == off1) return nums2[off2 + k - 1];
        if (nums2 == null || nums2.length == off2) return nums1[off1 + k - 1];
        if (k == 1) return Math.min(nums1[off1], nums2[off2]);
        int m = nums1.length - off1;
        int n = nums2.length - off2;
        if (m > n) return findKth(nums2, nums1, off2, off1, k);
        int part1 = Math.min(k / 2, m);
        int part2 = k - part1;
        if (nums1[off1 + part1 - 1] < nums2[off2 + part2 - 1])
            return findKth(nums1, nums2, off1 + part1, off2, k - part1);
        else if (nums1[off1 + part1 - 1] > nums2[off2 + part2 - 1])
            return findKth(nums1, nums2, off1, off2 + part2, k - part2);
        else
            return nums1[off1 + part1 - 1];
    }
}

猜你喜欢

转载自likesky3.iteye.com/blog/2226623