4、两个有序数组的中位数

  1. 4、两个有序数组的中位数
    1. 示例 1:
    2. 示例 2:
  2. 题解
    1. 1、二分查找 划分数组
  3. 2、二分查找

4、两个有序数组的中位数


给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays

题解

1、二分查找 划分数组

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        // 分别获得两个数字的长度
        int m = nums1.length;
        int n = nums2.length;
        // 第一个数组必须是元素较少的数组,否则交换
        if (m > n) {
            int[] tmp = nums1;
            nums1 = nums2;
            nums2 = tmp;
            m = m^n;
            n = n^m;
            m = m^n;
        }
        // 二分查找满足条件的中位数
        // 必须满足两个条件:1、左右两边的元素个数相等或者差一个元素
        // 对角元素小于等于关系,保证右半部分的最小值大于等于左半部分的最大值
        int iMin = 0,iMax = m,halfLen = (m + n + 1)/2;
        while(iMin <= iMax) {
            int i = (iMin + iMax)/2;
            int j = halfLen - i;// 保证j始终满足:j + i = m - i + n - j + 1; 
            if (i < iMax && nums2[j - 1] > nums1[i]) {
                iMin = i + 1; // i 太小
            } else if (i > iMin && nums1[i - 1] > nums2[j]) {
                iMax = i - 1; // i 太大
            } else { // 找到i了
                int maxLeft = 0;
                // 特殊情况处理
                if (i == 0) { maxLeft = nums2[j - 1]; }
                else if (j == 0) { maxLeft = nums1[i - 1];}
                else {
                    maxLeft = Math.max(nums1[i - 1],nums2[j - 1]);
                }
                // 总元素数量为奇数
                if ((m + n)%2 == 1) { return maxLeft;}
                
                int minRight = 0;
                if (i == m) {
                    minRight = nums2[j];
                } else if (j == n) {
                    minRight = nums1[i];
                } else {
                    minRight = Math.min(nums1[i],nums2[j]);
                }
                // 总元素数量为偶数
                return (maxLeft + minRight) / 2.0;
            }
        }
        return 0.0;
    }
}

2、二分查找

两个有序数组,二分查找取中位数

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1 = nums1.length, len2 = nums2.length;
        int totalLength = len1 + len2;
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1);
            return median;
        } else {
            int midIndex1 = totalLength / 2 - 1,midIndex2 = totalLength / 2;
            double median = (getKthElement(nums1,nums2,midIndex1 + 1) + getKthElement(nums1,nums2,midIndex2 + 1)) / 2.0;
            return median;
        }
    }
    // 获取两个有序数组,第K的元素
    private int getKthElement(int[] nums1,int[] nums2,int k) {
        int length1 = nums1.length,length2 = nums2.length;
        int index1 = 0,index2 = 0;
        int kthElement = 0;

        while (true) {
            // 边界情况
            if(index1 == length1) {
                return nums2[index2 + k - 1];
            }
            if (index2 == length2) {
                return nums1[index1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[index1], nums2[index2]);
            }

            // 正常二分
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1;
            int newIndex2 = Math.min(index2 + half,length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2) {
                // 排除一部分
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            } else {
                // 排除一部分
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

💰

Title:4、两个有序数组的中位数

Count:704

Author:攀登

Created At:2020-07-26, 00:19:44

Updated At:2024-06-15, 15:52:32

Url:http://jiafeimao-gjf.github.io/2020/07/26/4%E3%80%81%E4%B8%A4%E4%B8%AA%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E4%B8%AD%E4%BD%8D%E6%95%B0/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

×

Help us with donation