美文网首页
4. Median of Two Sorted Arrays |

4. Median of Two Sorted Arrays |

作者: kid551 | 来源:发表于2018-08-29 08:37 被阅读0次

最直观的解法是使用寻找一个数组中第k个元素的方式。

public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length, n = nums2.length,
                left = (m + n + 1) / 2, right = (m + n + 2) / 2;
        return (findKth(nums1, nums2, left) + findKth(nums1, nums2, right)) / 2.0;
    }
    int findKth(int[] nums1, int[] nums2, int k) {
        int m = nums1.length, n = nums2.length;
        if (m > n) return findKth(nums2, nums1, k);
        if (m == 0) return nums2[k - 1];
        if (k == 1) return Math.min(nums1[0], nums2[0]);
        int i = Math.min(m, k / 2), j = Math.min(n, k / 2);
        if (nums1[i - 1] > nums2[j - 1]) {
            return findKth(nums1, Arrays.copyOfRange(nums2, j, n), k - j);
        } else {
            return findKth(Arrays.copyOfRange(nums1, i, m), nums2, k - i);
        }
    }
}

这段代码的一个难点是,

int i = Math.min(m, k / 2), j = Math.min(n, k / 2);
if (nums1[i - 1] > nums2[j - 1]) {
    return findKth(nums1, Arrays.copyOfRange(nums2, j, n), k - j);
} else {
    return findKth(Arrays.copyOfRange(nums1, i, m), nums2, k - i);
}

为什么找寻到k/2个元素和各自数组长度的最小值所对应的数组值后,就可以将另一部分砍掉?

例如,

if (nums1[i - 1] > nums2[j - 1]) {
    return findKth(nums1, Arrays.copyOfRange(nums2, j, n), k - j);
} 

这就把nums2的前半部分砍掉了。为什么呢?我们可以用反证法做推理。砍掉nums2的前半部分,无非是说:在这里面,一定不存在我们要搜寻的合并后数组的第k个元素

假设存在,那么,合并两个数组时,一定是nums2的至少前k/2个元素(因为我们假设了第k个元素在这前半段),和nums1的至少前k/2个元素(否则,将无法从别处找到元素来填充构成合并数组的前k个元素。这条可以从两个数组的单调递增看出来)来组成整个的合并数组。

此时,nums1[i]就被放在了nums2的前半段,这就与nums1[i]大于nums2[j]相矛盾。

同理可证nums1[i]小于等于nums2[j]的情况。

相关文章

网友评论

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

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