在两个长度相等的排序数组中找到上中位数

该博客主要介绍了如何在两个长度相等的有序数组中寻找上中位数,通过双指针法和二分法实现。要求时间复杂度为O(logN),额外空间复杂度为O(1)。首先使用双指针法找出初步结果,但其时间复杂度为O(n)。接着采用二分法,根据数组中间元素的比较调整搜索范围,最终达到目标时间复杂度。博客详细解释了不同情况下的处理策略,并提供了代码实现。
摘要由CSDN通过智能技术生成

题目地址:
https://www.nowcoder.com/practice/6fbe70f3a51d44fa9395cfc49694404f?tab=answerKey

题目描述
给定两个有序数组arr1和arr2,已知两个数组的长度都为N,求两个数组中所有数的上中位数。
上中位数:假设递增序列长度为n,若n为奇数,则上中位数为第n/2+1个数;否则为第n/2个数
[要求]
时间复杂度为O(logN),额外空间复杂度为O(1)O(1)

这题简单点的思路,其实就是一个双指针,
1.index1,指向数组arr1,index2指向数组arr2,
2.arr1[index1]>arr2[index2],index2++,否则 index1++
3.然后直到index1+index2 等于数组的长度,输出最后移动的指针指向的数字即可

代码实现如下:

public int findMedianinTwoSortedAray(int[] arr1, int[] arr2) {
        int index1 = 0;
        int index2 = 0;
        int length = arr1.length;
        while (index1+index2<length-1){
            if (arr1[index1]<arr2[index2]){
                index1++;
            }else {
                index2++;
            }
        }
        return Math.min(arr1[index1],arr2[index2]);
   }

但是这个算法的时间复杂度达到了O(n),不符合题目要求。所以,基本上,一般看到要求时间复杂度为O(logN),基本上能做的就是二分法了,

1.取两个数组的中间位置,mid1,mid2

2.如果 arr1[mid1] == arr2[mid2],则得到结果 返回arr1[mid1]即可,

3.arr1[mid1]>arr2[mid2],
数组arr1中mid1位置以后的数都不可能是整体的上中位数,数组arr2中mid2位置以前的数都不可能是整体的上中位数。所以现在只需要考虑arr1[left1…mid1]、arr2[mid2…right],这两部分的元素个数相同,它们的上中位数就是整体的上中位数。

然后分一下数组长度的奇偶情况,

3.1同样arr1[mid1]>arr2[mid2],
如果当前数组长度是偶数,只需要 留下 arr1 :[left1,mid1] arr2(mid2,right2]
如果当前数组长度是奇数,只需要 留下 arr1 :[left1,mid1] arr2[mid2,right2]
在这种情况下,可以看到 arr2 的右边因为数组长度分奇偶,而导致了开合。这样做是为了保证arr1 剩余长度等于 arr2 剩余长度。

4.如果arr1[mid1]<arr2[mid2]
如果当前数组长度是偶数,只需要 留下 arr1 :(mid1,right1] arr2[left2,mid2]
如果当前数组长度是奇数,只需要 留下 arr1 :[left1,mid1] arr2[mid2,right2]

示意图如下
在这里插入图片描述

实现代码如下:

 public int findMedianinTwoSortedAray(int[] arr1, int[] arr2) {

        return find(arr1,0,arr1.length,arr2,0,arr2.length);
    }

    int find(int[] arr1, int left1, int rigth1, int[] arr2, int left2, int rigth2) {
        int mid1 = (rigth1 - left1-1) / 2 + left1;
        int mid2 = (rigth2 - left2-1) / 2 + left2;

        if (arr1[mid1]==arr2[mid2]){
            return arr1[mid1];
        }
        if (rigth1 - left1 == 1){
            return Math.min(arr1[left1],arr2[left2]);
        }

        if ((rigth1-left1)%2==1){
            if (arr1[mid1]>arr2[mid2]){
                return find(arr1,left1,mid1+1,arr2,mid2,rigth2);
            }else {
                return find(arr1,mid1,rigth1,arr2,left2,mid2+1);
            }
        }else {
            if (arr1[mid1]>arr2[mid2]){
                return find(arr1,left1,mid1+1,arr2,mid2+1,rigth2);
            }else {
                return find(arr1,mid1+1,rigth1,arr2,left2,mid2+1);
            }
        }

    }

重点推理,就是每次二分之后剩余的数组的中上位数,为全部数组的中上位数。大家可以用画图的方案,来推理一下。
然后要分一下奇数偶数中间位保留跟丢弃的情况。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ocean曈

您的支持,是我创作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值