leetcode 4. Median of Two Sorted Arrays

本文介绍了一种高效算法,用于找出两个已排序数组的中位数,时间复杂度达到O(log(min(m,n)))。通过二分查找确定中位数所在位置,确保了算法的高效运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

You may assume nums1 and nums2 cannot be both empty.

Example 1:

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

The median is 2.0
Example 2:

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

The median is (2 + 3)/2 = 2.5

给出两个排列好的数组,找出这两个数组组合起来的元素的中值

思路:
所有元素扫描一遍找中值的话时间复杂度是O(m+n),而题中要求O(log(m+n)),考虑到binary search

假如总长度是n,那么中值应该在n/2的位置(n是奇数时)
这个n/2位置的前半部分由nums1的m1个元素,nums2的m2个元素组成,所以只要知道了m1,就能知道m2 ( m2 = n/2 - m1)

所以现在的目标是找到m1

假如
nums1 = [ 1, 2, | 5, 6 ]
nums2 = [ 3, 4, | 7, 8 ]
nums = [1, 2, 3 , 4 | 5, 6, 7, 8]

先取m1为nums1的中点,m1取2, 那么m2=2
因为是排好序的,最大元素在最右边

nums1和nums2的前半段最后一个元素中较大的,是合并数组nums的前半段中值。
后半段第一个元素中较小的,是nums的后半段中值。

nums2前半段最后一个元素nums2[m2-1] < nums1后半段第一个元素nums1[m1]

如果nums1[m1] < nums2[m2-1]就说明nums1的分段要更靠后,left = m1+1
否则right = m1, 就是用binary search找到合适的分段点m1

时间复杂度是O(log(min(m, n)))

//2ms
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return findMedianSortedArrays(nums2, nums1);
        }
        
        int n1 = nums1.length;
        int n2 = nums2.length;
        int left = 0;
        int right = n1; //if =n1-1, then if only 1 element, won't go loop
        int k = (n1 + n2 + 1) / 2;
        int m1 = 0;
        int m2 = 0;
        
        //get m1 elements from nums1..
        while (left < right) {
            m1 = left + (right - left) / 2;
            m2 = k - m1;
            if (nums1[m1] < nums2[m2 - 1]) {
                left = m1 + 1;
            } else {
                right = m1;
            }
        }
        
        m1 = left;
        m2 = k - m1;
        
        int c1 = Math.max((m1 <= 0) ? Integer.MIN_VALUE : nums1[m1 - 1],
                         (m2 <= 0) ? Integer.MIN_VALUE : nums2[m2 - 1]);
        
        int c2 = Math.min((m1 >= n1) ? Integer.MAX_VALUE : nums1[m1],
                          (m2 >= n2) ? Integer.MAX_VALUE : nums2[m2]);
        
        if ((n1 + n2) % 2 == 1) {
            return c1;
        } else {
            return (c1 + c2) / 2.0;
        }
        
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值