LeetCode4.尋找兩個有序數組的中位數(有圖助於理解)

聲明:

使用C語言,結合函數 double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) 詳細說明

解題思路:

一個長度爲 nums1Size 的數組,到 nums1Size 總共有 nums1Size 個位置可以切Cut

比如說 nums1Size = 3 

我們把數組 nums1 和 nums2 分別在 和 位置上切割

的左邊和 的左邊組成左半部分, 的右邊和 的右邊組成右半部分。左半部分的長度等於右半部分

i的初始位置爲 num1Size/2
i+j=nums1Size-i+nums2Size-j => j=(nums1Size+nums2Size)/2-i

+1是將兩個數組總長度是奇數情況下考慮進去,兩個數組總長度是奇數時,左半部分的長度等於右半部分加1。
因爲我們取的是int值,不影響上述結果。
j=(nums1Size+nums2Size+1)/2-i

以下分爲兩種情況討論:

當 nums2[ j - 1 ] > nums1[ i ] 時,需要向右移,即 增大

當 nums1[ i - 1 ] > nums2[ j ] 時,需要向左移,即 減小

兩種情況 會隨着 變化而變化。

直到滿足條件 "左半部分最大的值小於等於右半部分最小的值 max( nums1[ i - 1 ] ,  nums2[ j - 1 ] )  <= 

min( nums1[ i ],  nums2[ j ] ) " 進行以下討論。

切到邊界(0nums1Size)情況下,

  當 i = 0 時,左半最大值 = nums2[ j - 1 ]

  當 i = nums1Size 時,右半最小值 = nums2[ j ]

j 切到邊界亦是如此;

當兩個數組總長度是奇數時,中位數來自 max( nums1[ i - 1 ] ,  nums2[ j - 1 ]),即左半最大值。

當兩個數組總長度是偶數時,中位數來自 [ max( nums1[ i - 1 ],  nums2[ j - 1 ] ) + min( nums1[ i ],  nums2[ j ] ) ] / 2,也就是左半部分的最大值加右半部分最小值除於2。

 

本人github:https://github.com/Tomy-Enrique/LeetCode

以下代碼參考:

#include <iostream>
//#include <algorithm>
using namespace std;

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
    if(nums1Size > nums2Size){      //保證數組1一定最短
        return findMedianSortedArrays(nums2, nums2Size, nums1, nums1Size);
    }
    
    int iMin = 0, iMax = nums1Size;
    int maxLeft = 0, minRight = 0;
    while (iMin <= iMax)
    {
        //i爲第一個數組的割,j爲第二個數組的割
        int i = (iMin + iMax) / 2;
        int j = (nums1Size + nums2Size + 1) / 2 - i;
        //cout << i << " "<< j << endl;
        
        if(j != 0 && i != nums1Size && nums2[j-1] > nums1[i]){      //i需要增大
            iMin = i+1;
        }
        else if(i != 0 && j != nums2Size && nums1[i - 1] > nums2[j] ){ //i需要減小
            iMax = i-1;
        }
        else{   //滿足條件 max(nums1[i-1], nums2[j-1]) <= min(nums1[i], nums2[j])   
            if(i == 0){
                maxLeft = nums2[j-1];
            }
            else if(j == 0){
                maxLeft = nums1[i-1];
            }
            else{
                maxLeft = nums1[i-1] > nums2[j-1] ? nums1[i-1] : nums2[j-1];
            }

            if(i == nums1Size && j == nums2Size){
                minRight = 0;
            }
            else if(i == nums1Size){
                minRight = nums2[j];
            }
            else if(j == nums2Size){
                minRight = nums1[i];
            }
            else{
                minRight = nums1[i] > nums2[j] ? nums2[j] : nums1[i];
            }

            if((nums1Size + nums2Size) % 2 == 1){
                return maxLeft;
            }else{
                return (maxLeft + minRight) / 2.0;
            }            
        }
    }
    return 0.0;
}

int main()
{
    int nums1[4] = {2, 3, 5, 6};
    int nums2[4] = {1, 4, 7, 9};
    int nums3[2] = {1, 2};
    int nums4[2] = {-1, 3};
    
    cout << findMedianSortedArrays(nums3, 2, nums4, 2);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章