Skip to content
Rain Hu's Workspace
Go back

[LeetCode] 4. Median of Two Sorted Arrays

Rain Hu

4. Median of Two Sorted Arrays


一、題目

Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the sorted arrays.
The overall run time complexity should be O(log (m+n)).

Example 1:

Example 2:

Constraints:


二、分析

三、解題

1. Brute Method

double findMedianSortedArray(vector<int>& nums1, vector<int>& nums2) {
    int m = nums1.size(), n = num2.size();
    vector<int> nums;       // 先將兩個數組 merge 後再求 median
    int i = 0, j = 0;
    while (i < m && j < n) {
        if (nums1[i] < nums2[j])
            nums.push_back(nums1[i++]);
        else
            nums.push_back(nums2[j++]);
    }
    while (i < m) nums.push_back(nums1[i++]);
    while (j < n) nums.push_back(nums2[j++]);

    int len = nums.size();
    // 若數組長度為奇數則回傳中間的值,若為偶數則為中間兩數的平均。
    return (len & 1) ? (nums[len/2]/1.0) : (nums[len/2-1] + nums[len/2])/2.0;
}

2. Kth Element

vector<int> nums1, nums2
int m, n;

// nums1 確定有 i 個元素小於 median,nums2 中確定有 j 個元素小於 median,求第 k 個元素
double kth(int i, int j, int k) {   
    if (i == m) return nums2[j+k-1];    // nums1 用完了,直接對 nums2 取第 j+k 個元素
    if (j == n) return nums1[i+k-1];    // nums2 用完了,直接對 nums1 取第 i+k 個元素
    if (k == 1) return min(nums1[i], nums2[j]); //當前比較小的即為第 k 個元素

    int mid1 = (i+k/2-1) >= m ? INT_MAX : nums1[i+k/2-1];
    int mid2= (i+k/2-1) >= n ? INT_MAX : unms2[j+k/2-1];

    // 兩個數組都往前推 k/2 個,其當前值較小的,其數組前 k/2 個數必定小於 median
    if (mid1 < mid2)
        return kth(i+k/2, j, k-k/2);
    else
        return kth(i, j+k/2, k-k/2);
}

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    this->nums1 = nums1;
    this->nums2 = nums2;
    this->m = nums1.size();
    this->n = nums2.size();
    int len = m + n;
    // 若數組長度為奇數則回傳中間的值,若為偶數則為中間兩數的平均。
    if (len & 1) return kth(0, 0, len/2+1)/1.0;
    return (kth(0, 0, len/2) + kth(0, 0, len/2+1))/2.0;
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    int m = nums1.size(), n = nums2.size();
    int len = m + n;
    // 確保 nums1 的長度比較短,以減少時間複雜度
    if (m > n) return findMedianSortedArrays(nums2, nums1);
    int l = 0, r = m;
    int l1, l2, r1, r2;
    // binary search
    while (l <= r) {
        int cut1 = (l+r)/2;
        int cut2 = (len+1)/2 - cut1;    // 注意 len+1
        l1 = cut1 == 0 ? INT_MIN : nums1[cut1-1];
        l2 = cut2 == 0 ? INT_MIN : nums2[cut2-1];
        r1 = cut1 == m ? INT_MAX : nums1[cut1];
        r2 = cut2 == n ? INT_MAX : nums2[cut2];
        if (l1 <= r2 && l2 <= r1) {     // median 必定為 l1 或 l2
            break;
        } else if (l1 > r2) {
            r = cut1-1;
        } else {
            l = cut1+1;
        }
    }
    if (len & 1) return max(l1, l2)/1.0;
    return (max(l1, l2) + min(r1, r2))/2.0;
}

回目錄 Catalog


Share this post on:

Previous
[LeetCode] 5. Longest Palindromic Substring
Next
[LeetCode] 3. Longest Substring Without Repeating Characters