1. 程式人生 > >LeetCode演算法題——兩個排序陣列的中位數

LeetCode演算法題——兩個排序陣列的中位數

4.給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2 

請找出這兩個有序陣列的中位數。要求演算法的時間複雜度為 O(log (m+n)) 。

你可以假設 nums1 和 nums2 不同時為空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

中位數是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

中位數是 (2 + 3)/2 = 2.5

這道題對於兩個有序且不同為空的陣列,首先先對其中一個為空的左判斷,兩個判斷之後,如果總長度為偶數的話中位數就是由左中位數加右中位數之和除以2,為奇數就是直接返回右中位數,所以只要同時找到左中位數和右中位數就可以解了,而對兩個排序的陣列找到他們的中位數就可以用歸併排序(我之前的部落格有提到歸併排序),程式碼如下:

//兩個排序陣列的中位數
public static double FindMedianSortedArrays(int[] nums1, int[] nums2)
{
    int length1 = nums1.Length;
    int length2 = nums2.Length;
    if (length1 == 0)  //對其中一個數組為空做判斷
    {
        if ((length2 & 1)== 0) return 1.0 * (nums2[length2 / 2] + nums2[(length2 - 1) / 2]) / 2;
        else {
            return 1.0 * nums2[length2 / 2];
        }
    }
    if (length2 == 0)
    {
        if ((length1 & 1) == 0) return 1.0 * (nums1[length1 / 2] + nums1[(length1 - 1) / 2]) / 2;
        else
        {
            return 1.0 * nums1[length1 / 2];
        }
    }
    int nums1Start = 0;   //nums1索引
    int nums2Start = 0;   //nums2索引
    int left = 0;       //儲存左中位數
    int right = 0;      //儲存右中位數
    for (int i = 0; i <= (length1 + length2) / 2; i++) {
        left = right;
        //同歸並原理一樣,對兩個有序的陣列進行排序;可以看我之前的歸併排序部落格
        if (nums1Start < length1 && (nums2Start >= length2 || nums1[nums1Start] < nums2[nums2Start]))
        {
            right = nums1[nums1Start++];
        }
        else {
            right = nums2[nums2Start++];
        }
    }
    if (((length1 + length2) & 1) == 0) return 1.0 * (left + right) / 2;
    else return 1.0 * right;
}