力扣(LeetCode) 4.寻找两个正序数组的中位数(java)

题目

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 。

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

第一种:二分

public class FindMedianSortedArrays {

    public static void main(String[] args) {
        int[] nums1 = {1};
        int[] nums2 = {2,3,4,5,6};
        System.out.println(new FindMedianSortedArrays().findMedianSortedArrays(nums1, nums2));
    }

    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        //比如总共6个数,结果是第三第四求平均数,那目标就是找到第三小的和第四小的数
        //求中间值 K 总长为 len
        //len为奇,left k=len+1/2、right k=len+2/2 向下取整 值一样。len为偶,left k=len+1/2、right k=len+2/2

        int len = nums1.length + nums2.length;
        int left = getVal((len+1)/2, nums1, 0, nums2, 0);
        int right = getVal((len+2)/2, nums1, 0, nums2, 0);

        return (left+right)/2.0;
    }

    private int getVal(int k, int[] nums1, int start1, int[] nums2, int start2) {


        if (start1>=nums1.length) {
            return nums2[start2+k-1];
        }
        if (start2>=nums2.length) {
            return nums1[start1+k-1];
        }
        if (k == 1) {
            return Math.min(nums1[start1], nums2[start2]);
        }

        int l = k/2;

        int s1 = start1+l-1 >= nums1.length ? Integer.MAX_VALUE : nums1[start1+l-1];
        int s2 = start2+l-1 >= nums2.length ? Integer.MAX_VALUE : nums2[start2+l-1];

        return s1 < s2 ? getVal(k-l, nums1, start1+l, nums2, start2) : getVal(k-l, nums1, start1, nums2, start2+l);
    }

}

LeetCode测试结果

 

示例代码

class Solution {
   public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;
        int left = (m + n + 1) / 2;
        int right = (m + n + 2) / 2;
        return (getKth(nums1, 0, m - 1, nums2, 0, n - 1, left) + getKth(nums1, 0, m - 1, nums2, 0, n - 1, right)) * 0.5;
    }

    private double getKth(int[] nums1, int i, int i1, int[] nums2, int i2, int i3, int left) {
        int m = i1 - i + 1;
        int n = i3 - i2 + 1;
        if (m > n) {
            return getKth(nums2, i2, i3, nums1, i, i1, left);
        }
        if (m == 0) {
            return nums2[i2 + left - 1];
        }
        if (left == 1) {
            return Math.min(nums1[i], nums2[i2]);
        }
        int i4 = i + Math.min(m, left / 2) - 1;
        int i5 = i2 + Math.min(n, left / 2) - 1;
        if (nums1[i4] > nums2[i5]) {
            return getKth(nums1, i, i1, nums2, i5 + 1, i3, left - (i5 - i2 + 1));
        } else {
            return getKth(nums1, i4 + 1, i1, nums2, i2, i3, left - (i4 - i + 1));
        }
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值