两个升序数组的中位数
本文最后更新于 64 天前。

方法一:二路归并

两个升序数组可以使用双指针的方式在$O(n)$的时间内归并为一个升序的大数组,已知个数,可以直接求出中位数。

方法二:快速选择

求中位数相当于求第k大的数,对于一个数组求第k大的数可以用快速选择,时间复杂度$O(n)$,但是这里就没有用到两个数组有序的性质

方法三:分割线+二分,时间复杂度$O(log(min(m, n)))$

官方题解视频链接:【4. 寻找两个正序数组的中位数 Median of Two Sorted Arrays 【LeetCode 力扣官方题解】】https://www.bilibili.com/video/BV1Xv411z76J?vd_source=50714aba974e807c499d6a482d48a437

在一个一维数组里,我们可以使用分割线求中位数,如果是偶数,分割线左右元素个数相等,左边均<=右边,这样(左边最大的数+右边最小的数)/ 2.0就是中位数,如果是奇数,可以规定左边元素比右边元素多一个,左边均<=右边,这样左边最大的元素就是中位数。

对于两个数组,也可以画一条这样的分割线,如图,分割线左边均<=右边,偶数奇数情况与上面相同。由于两个数组都是升序,所以对于分割线左边均<=右边这个条件,我们只需要保证A[i – 1] <= B[j],B[j – 1] <= A[i],(i,j表示第一个和第二个数组分割线后面一个元素的下标,这样i,j还可以表示第一个和第二个数组分割线左边元素个数)对于第一个数组,i的取值范围是[0,nums1Size],注意两个边界,对于第二个数组,j的取值范围是[0,nums2Size],我们可以二分得出较小数组的分割线i的位置,对于每个i,j都是确定的,因为j = 分割线左边元素总个数 – i。二分方法:较小数组可以根据性质:A[i – 1] <= B[j],分为两部分,左边满足这个性质,右边不满足,左边和右边区间就是由分割线分割开的,可以求左边区间的最右边的端点,加一就是分割线的位置i。求出i后,还要注意特殊处理特殊情况防止数组访问越界。

int max(int a, int b){return a > b ? a : b;}
int min(int a,int b){return a < b ? a : b;}
void swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
    if(nums1Size > nums2Size){
        int *temp = nums1;
        nums1 = nums2;
        nums2 = temp;
        swap(&nums1Size, &nums2Size);
    }
    int l = 0, r = nums1Size;
    int leftSum = nums1Size + nums2Size + 1 >> 1;
    while(l < r){
        int mid1 = l + r + 1 >> 1;
        int mid2 = leftSum - mid1;
        if(nums1[mid1 - 1] <= nums2[mid2])l = mid1;
        else r = mid1 - 1;
    }
    if((nums1Size + nums2Size) % 2 == 1){
        if(l - 1 >= 0 && leftSum - l - 1 >= 0)return max(nums1[l - 1], nums2[leftSum - l - 1]);
        else if(l - 1 >= 0)return nums1[l - 1];
        else return nums2[leftSum - l - 1];
    } else {
        int leftMax, rightMin;
        if(l - 1 >= 0 && leftSum - l - 1 >= 0)leftMax = max(nums1[l - 1], nums2[leftSum - l - 1]);
        else if(l - 1 >= 0)leftMax = nums1[l - 1];
        else leftMax = nums2[leftSum - l - 1];
        if(l < nums1Size && leftSum - l < nums2Size)rightMin = min(nums1[l], nums2[leftSum - l]);
        else if(l < nums1Size)rightMin = nums1[l];
        else rightMin = nums2[leftSum - l];
        return (leftMax + rightMin)/2.0;
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇