【leetcode】寻找两个有序数组的中位数【C++】

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/qq_34018840/article/details/89239710

题目如下:

解题思路:

因为时间复杂度要求为 O( log(m+n) ),所以显然需要采用二分或者分治的方法来做,这题参考找第 k 个数的思想来做,每次排除 k/2 个数,时间复杂化度 O(logk)

代码如下(C++):

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        //用查找第"k"个数的思想来做(数组的第一个元素从1开始计数)
        int n = nums1.size(), m = nums2.size();
        //注意C++中奇数直接除以2后并不是中位数,需要加1,例如 5 / 2 = 2;
        int len = (n + m) / 2 + 1;
        //按奇偶讨论
        if ((n + m) % 2 == 1){
            return findK(nums1, 0, nums2, 0, len);
        } 
        else{
            return (findK(nums1, 0, nums2, 0, len - 1) + findK(nums1, 0, nums2, 0, len)) / 2.0;
        }
    }
    //i和j为A、B数组的起始位置
    //注意k相对数组是从1开始计数的,代表元素的真实排序位置
    //而i、j相对数组是从0开始计数的,代表元素在数组中的索引位置
    int findK(vector<int> A, int i, vector<int> B, int j, int k) {
        //一个数组全都被舍弃后直接返回
        if (i >= A.size()){
            return B[j + k - 1];
        }
        if (j >= B.size()){
            return A[i + k - 1];
        }
        //边界情况
        if (k == 1){
            return min(A[i], B[j]);
        }
        //舍弃较小的前k/2个数
        //如果某个数组可能越界就舍弃另一个数组的前k/2个数
        int A_key = i + k / 2 - 1 < A.size() ? A[i + k / 2 - 1] : INT_MAX;
        int B_key = j + k / 2 - 1 < B.size() ? B[j + k / 2 - 1] : INT_MAX;
        //舍弃k/2个数后,问题变为查找第k - k / 2个数
        if (A_key < B_key){
            return findK(A, i + k / 2, B, j, k - k / 2);
        }else{
            return findK(A, i, B, j + k / 2, k - k / 2);
        }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_34018840/article/details/89239710
今日推荐