1. 程式人生 > >LeetCode 4. Median of Two Sorted Arrays (求兩個有序陣列第k大數字,分治法)

LeetCode 4. Median of Two Sorted Arrays (求兩個有序陣列第k大數字,分治法)

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

解法
一言難盡。。貼個圖自己記錄下吧。。
在這裡插入圖片描述

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        def kMin(l1, r1, l2, r2, k)
: if l1 > r1: return nums2[l2 + k - 1] if l2 > r2: return nums1[l1 + k - 1] mid1 = (l1 + r1) >> 1 mid2 = (l2 + r2) >> 1 mid = mid1 - l1 + mid2 - l2 + 2 if nums1[mid1] > nums2[
mid2]: if mid > k: # 捨去x右半段 return kMin(l1, mid1-1, l2, r2, k) else: # 捨去x左半段 return kMin(l1, r1, mid2 + 1, r2, k - (mid2 - l2 + 1)) else: if mid > k: # 捨去y的右半段 return kMin(l1, r1, l2, mid2-1, k) else: # 捨去x的左半段 return kMin(mid1 + 1, r1, l2, r2, k - (mid1 - l1 + 1)) n = len(nums1) m = len(nums2) key1 = (n+m)>>1 key2 = (n+m-1)>>1 if key1 == key2: return kMin(0, n-1, 0, m-1, key1+1) else: return (kMin(0, n-1, 0, m-1, key1+1) + kMin(0, n-1, 0, m-1, key2+1))/2

這是網上找的cpp程式碼,思路一致

class Solution {
public:

    int find(vector<int>& x, vector<int>& y, int xbeg, int xend, int ybeg, int yend, int k){
        if(xbeg > xend){
            return y[ybeg + k - 1];
        }
        if(ybeg > yend){
            return x[xbeg + k -1];
        }

        int xmid = (xbeg + xend)/2;
        int ymid = (ybeg + yend)/2;
        int halfLen = xmid - xbeg + ymid - ybeg + 2;

        if(x[xmid] < y[ymid]){//在合併的陣列中,原X[xbeg...xmid]所有元素一定在Y[ymid]的左側
            if(k < halfLen){// y的右半段不需要尋找了
                return find(x, y, xbeg, xend, ybeg, ymid-1, k);
            }else{// x的左半段不需要尋找了,因為X[xmid]<Y[ymid],所以極端情況x[xmid]也只能是k-1小的元素,所以取xmid+1到xend
                return  find(x, y, xmid+1, xend, ybeg, yend,  k-(xmid-xbeg+1));//注意k值的改變
            }
        }else{//在合併的陣列中,原Y[yBeg...yMid]的所有元素一定在X[xMid]的左側
            if(k < halfLen){
                return find(x, y, xbeg, xmid-1, ybeg, yend, k);
            }else{
                return find(x, y, xbeg, xend, ymid+1, yend, k-(ymid-ybeg+1));
            }
        }
    }

    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size(), m = nums2.size();
        int key1 = (n+m)/2, key2 = (n+m-1)/2;
        key1++; key2++;
        if(key1!=key2) 
            return (double(find(nums1, nums2, 0, n-1, 0, m-1, key1)) + double(find(nums1, nums2, 0, n-1, 0, m-1, key2)))/2.0;
        else
            return find(nums1, nums2, 0, n-1, 0, m-1, key1);
    }
};