leetcode 4 寻找两个正序数组的中位数(困难)

4 寻找两个正序数组的中位数(困难)

给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数

示例:

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

解题思路:

给定两个有序数组,要求找到两个有序数组的中位数,最直观的思路有以下两种:

  • 使用归并的方式,合并两个有序数组,得到一个大的有序数组。大的有序数组的中间位置的元素,即为中位数。

  • 不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 00 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。

假设两个有序数组的长度分别为 m 和 n,第一种思路的时间复杂度是 O(m+n),空间复杂度是 O(m+n)。第二种思路虽然可以将空间复杂度降到 O(1),但是时间复杂度仍是 O(m+n)。

时间复杂度为log(m+n)的解法:二分查找

1、C++:归并

创建一个新的数组来存储num1和mun2拼接之后的结果,然后取其中位数。拼接时可指定两个指针,分别遍历nums1和nums2,并取nums1[i]和nums2[j]中较小的元素存储到新数组中,然后较小元素数组指针加一。时间复杂度为O(m+n)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        vector<int> res(m+n);
        int i=0,j=0,k=0;
        while(i<m && j<n){
            if (nums1[i]<=nums2[j]){
                res[k] = nums1[i];
                k++;
                i++;
            }
            else{
                res[k] = nums2[j];
                k++;
                j++;
            }
        }
        while(i<m){
            res[k] = nums1[i];
            k++;
            i++;
        }
        while(j<n){
            res[k] = nums2[j];
            k++;
            j++;
        }
        if((m+n)%2 == 0 )
            return (res[(m+n)/2]+res[(m+n-1)/2])/2.0;
        else
            return res[(m+n)/2];
    }
};

二分查找法

解题思路:寻找两个有序数组的中位数 - 寻找两个正序数组的中位数 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
public:
    int getkthnum(vector<int>& nums1, vector<int>& nums2,int k){
        int m = nums1.size();
        int n = nums2.size();
        int i=0,j=0,p=0;
        while(true){
            if(i==m)
                return nums2[j+k-1];
            if(j==n)
                return nums1[i+k-1];
            if(k==1)
                return min(nums1[i],nums2[j]);//k=1时,也可能有i==m、j==n条件同时存在,因此此条件放后面
            p = k/2 -1;
            int newi = min(i+p ,m-1);//i+p可能会溢出
            int newj = min(j+p, n-1);
            if (nums1[newi]<=nums2[newj]){
                k=k-(newi-i+1);
                i=newi+1;
            }
            else{
                k = k-(newj-j+1);
                j = newj+1;
            }      
        }
    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        if((m+n)%2==0)
            return (getkthnum(nums1,nums2,(m+n)/2)+getkthnum(nums1,nums2,(m+n)/2+1))/2.0;
        else
            return getkthnum(nums1,nums2,(m+n)/2+1)        
    }   
};

2、python

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        m = len(nums1)
        n = len(nums2)
        res = []
        i,j = 0,0
        while(i<m and j<n):
            if nums1[i]<=nums2[j]:
                res.append(nums1[i])
                i=i+1
            else:
               res.append(nums2[j])
               j=j+1
        while(i<m):
            res.append(nums1[i])
            i=i+1
        while(j<n):
            res.append(nums2[j])
            j=j+1
        if (m+n)%2 ==0:
            return (res[(m+n)//2]+res[(m+n-1)//2])/2
        else:
            return res[(m+n)//2]
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        m = len(nums1)
        n = len(nums2)
        res = []
        res.extend(nums1)
        res.extend(nums2)
        res.sort()
        if (m+n)%2 ==0:
            return (res[(m+n)//2]+res[(m+n-1)//2])/2
        else:
            return res[(m+n)//2]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值