leetcode 每日打卡————「4. 寻找两个正序数组的中位数」

题目点击这里 ➡️「寻找两个正序数组的中位数」
思路(合并数组,寻找中位数):

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int[] nums = new int[nums1.length + nums2.length];
        int index=0,l1=0,l2=0;
        while (l1 < nums1.length && l2 < nums2.length) {
            if (nums1[l1] <= nums2[l2]) {
                nums[index] = nums1[l1];
                l1 ++;
            } else {
                nums[index] = nums2[l2];
                l2 ++;
            }
            index++;
        }
        if (l1 == nums1.length) {
            for (;l2 < nums2.length; l2 ++, index ++) {
                nums[index] = nums2[l2];
            }
        }
        if (l2 == nums2.length) {
            for (;l1 < nums1.length; l1 ++, index ++) {
                nums[index] = nums1[l1];
            }
        }
        if (nums.length % 2 != 0) {
            return Double.valueOf(nums[nums.length / 2]);
        }

        return (nums[nums.length / 2] + nums[nums.length / 2 - 1]) / 2.0;
    }

思路(二分法):
首先需要知道两个数组都是正序的,获得中位数就是两个数组中位置处于(m+n)/ 2 的那个数字,如果每次可以排除一些数字,最后剩下的就是想要获得的特定位置的数字;
假设给定两个数组A[m]、B[n],需要获得A、B两数组中第k小的数字「k=(m+n)/2」
如果我们取A[k/2]和B[k/2],则最多会有k+2个数字比这两个数字最小的大,导致无法排除不符合规则的数字,所以取A[k/2 - 1]和B[k/2 - 1] 来进行比较,若A[k/2 - 1] <= B[k/2 - 1],则A[0…k/2-1]都肯定不是正确结果,直接排出即可。

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1 = nums1.length, len2 = nums2.length;
        int len = len1 + len2;
        // 如果是奇数,返回对应位置的数
        if (len % 2 == 1) {
            return Double.valueOf(getKthNum(nums1, nums2, len / 2 + 1));
        }
        return (getKthNum(nums1, nums2, len / 2) + getKthNum(nums1, nums2, len / 2 + 1)) / 2.0;
    }

	// 获得第 k 小的数
    private int getKthNum(int[] nums1, int[] nums2, int k) {
        int len1 = nums1.length, len2 = nums2.length;
        int i1 = 0, i2 = 0;
        while (true) {
        	// 边界条件判断
            if (i1 == len1) {
                return nums2[i2 + k - 1];
            }
            if (i2 == len2) {
                return nums1[i1 + k - 1];
            }
            // k = 1,取排出元素后两个数组第一个数的最小值
            if (k == 1) {
                return Math.min(nums1[i1], nums2[i2]);
            }
            // 考虑数组越界情况
            int index1 = Math.min(k/2 + i1, len1) - 1, index2 = Math.min(k/2 + i2, len2) - 1;
            if (nums1[index1] <= nums2[index2]) {
            	// 排除不符合条件的数字
                k -= (index1 - i1 + 1);
                i1 = index1 + 1;
            } else {
                k -= (index2 - i2 + 1);
                i2 = index2 + 1;
            }
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值