寻找两个正序数组的中位数问题,方法二:双指针检索法

题目:

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。
示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3:

输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:

输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:

输入:nums1 = [2], nums2 = []
输出:2.00000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays

分析:

上回说到,这里的合并数组其实不是一定需要求得的,可以直接用指针来指示出中位数的位置,选取两个指针r1,r2,这里有一种思路是直接找出中间位,但是对于偶数的情况,有两个中间位,所以这里是双指针,r1指向的是现在的数,r2指向的是r1的上一个取值。另外就是循环执行的次数问题,这里是 (m+n)/2,当m+n是奇数的时候,直接向下取整,当m+n是偶数的时候,就是(m+n)/2和(m+n)/2-1刚好对应了r1和r2。
举个例子,a有2个元素,b有一个元素,则中间位就是3/2=1,执行两次到达,即k<=target,如果a有2个元素,b有2个元素,中间位是4/2=2,执行三次到达,前一位r2就是执行了两次的,所以就是(r1 + r2)/ 2.0。

代码:

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        //i,j分别是nums1,nums2的指示游标
        int i, j;
        i = j = 0;
        int sum = nums1.length + nums2.length;
        //target就是目标游标值
        int target = sum / 2;
        //flag表征奇偶性
        int flag = sum % 2;
        //记录结果,由于可能是偶数(两个中间值),所以需要有一个跟随变量r2存储r1的上一次值
        int r1,r2;
        r1 = r2 = 0;
        //遍历次数到达游标值target
        for(int k = 0; k <= target; k ++){
            //r2作为r1的跟随变量,记录上一次的值
            r2 = r1;
            //数组遍历查找,注意这里的&&和||都是短路处理的,防止数组越界
            //j>=nums2.length要写在nums1[i]<nums2[j]的前面,当j = nums2.length,可以避免数组越界
            if(i < nums1.length && (j >= nums2.length || nums1[i] < nums2[j])){
                //先赋值后i自加
                r1 = nums1[i ++];
            }else{
                r1 = nums2[j ++];
            }
        }
        //根据奇偶性确定最后值
        if(flag == 1){
            return r1;
        }else{
            //注意这里要隐式强制类型转换成float
            return (r1 + r2) / 2.0;
        }
        
    }
}

总结:

这里采用了双指针的方法,没有选择合并数组,所以将空间复杂度由O(m+n)降到了O(1),时间复杂度不变,还是O(m+n),注意一下,这里通过短路逻辑来避免数组越界。还有跟快的方法吗?比如,二分一下,有跳跃查找的思想来代替连续查找,是否会取得更好的效果呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值