leetcode第4题 两个有序数组的中位数

该博客探讨了如何在两个有序数组中找到中位数的问题,提供了两种解决方案。第一种方法是通过桶排序的思想,时间复杂度为O(n),空间复杂度为O(1)。第二种方法利用二分查找,通过找到分割点px和py,确保数组边界元素的关系,达到在四个边界元素中找到中位数的目的,其时间复杂度为O(log n)。

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

题意: 给定两个有序数组 nums1,nums2, 找到这些数中的中位数。

第一种解法: 仿照桶排序的算法找到第K个数。时间复杂度 O(n). 空间复杂度 O(1)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        if (m > n) return findMedianSortedArrays(nums2, nums1);
        if ((m + n)%2){
            return findKthNum(nums1, nums2, 0, 0,(m + n)/2);
        } else {
            return (findKthNum(nums1, nums2, 0, 0, (m + n)/2-1) + findKthNum(nums1, nums2, 0, 0, (m + n)/2)) / 2.0;
        }
    }
    int findKthNum(vector<int>& nums1, vector<int>& nums2, int st1, int st2, int k) {
        while(k >= 0){
            int temp1 = INT_MAX;
            int temp2 = INT_MAX;
            if (st1 < nums1.size()) temp1 = nums1[st1];
            if (st2 < nums2.size()) temp2 = nums2[st2];
            if (temp1 <= temp2) ++st1;
            else ++st2;
            if (k == 0) return temp1 <= temp2? temp1:temp2;
            --k;
        }
        return 0;
        
    }
};

 

第二种解法: 上一种解法明显更加直观简单,但对于有序数组更快的查询思路应该采用二分法查找。时间复杂度O(lg n)。

这种时候可能不是很容易想出来如何在两个数组中二分。我们可以这样尝试分这两个数组。找到一个分界点index为 px和 py

使得 px + py  = (nums1.lsize() + nums2.size()) / 2。如果在这种情况下满足max_l1 <= min_r2 && max_l2 <= min_r1。那么我们最后就可以在中间这4个数中间找中位数。

  • 这个时候就可以尝试使用二分法查找px的位置。为了解决溢出情况我么可以假设每个数组开头有一个INT_MIN,结尾有一个INT_MAX。
  • 代码如下:

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        if (m > n) return findMedianSortedArrays(nums2, nums1);
        int st = 0;
        int en = m;
        while(st <= en){
            int px = (st + en) / 2;
            int py = (m + n) / 2 - px;
            
            int maxl1 = (px == 0)? INT_MIN : nums1[px-1];
            int minr1 = (px == m)? INT_MAX : nums1[px];
            
            int maxl2 = (py == 0)? INT_MIN : nums2[py-1];
            int minr2 = (py == n)? INT_MAX : nums2[py];
            
            if(maxl1 <= minr2 && maxl2 <= minr1){
                if ((m + n)%2 == 0){
                    return (max(maxl1, maxl2) + min(minr1, minr2)) / 2.0;
                } else {
                    return min(minr1, minr2);
                }
            } else if (minr1 < maxl2){
                st = px + 1;
            } else{
                en = px - 1;
            }            
        }
        return 0.0;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值