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

 

 

 

参考:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/    中的解法3 getKth

即两有序数组,寻求第 K 小,可以比较 nums1[k / 2 - 1] 与 nums2[k / 2 - 1],其中小的那个数及其前面的数,都不可能是第 K 小,及可以排除前 xxx 个数,然后在剩余数组中寻找第 k - xxx 大.

所以以下对于每个数组来说,有下标来维护,表示 l1 之前的数都被删除了 (不包括 l1)

class Solution {
public:
    double findMedianSortedArrays(const vector<int>& nums1, const vector<int>& nums2) {
        int sz = nums1.size() + nums2.size();
        if(sz & 1) {
            return getKth(nums1, 0, (int)nums1.size() - 1, nums2, 0, (int)nums2.size() - 1, sz / 2 + 1);
        }
        return (getKth(nums1, 0, (int)nums1.size() - 1, nums2, 0, (int)nums2.size() - 1, sz / 2) +
                getKth(nums1, 0, (int)nums1.size() - 1, nums2, 0, (int)nums2.size() - 1, sz / 2 + 1)) * 0.5;
    }

private:
    // 获得两个有序数组的第 k 小元素: log(m + n) 复杂度
    int getKth(const vector<int> &nums1, int l1, int r1, const vector<int> &nums2, int l2, int r2, int k) {
        if(l1 > r1 || l2 > r2) {    // l1 > r1 即 nums1 为空, l2 > r2 同理
            return l1 > r1 ? nums2[l2 + k - 1] : nums1[l1 + k - 1];
        }
        if(k == 1) {                // k == 1, 直接处理
            return min(nums1[l1], nums2[l2]);
        }
        int idx1 = min(l1 + k / 2 - 1, r1);       // 从 l1 开始算, 第 k / 2 个数下标为 l1 + k / 2 - 1
        int idx2 = min(l2 + k / 2 - 1, r2);
        if(nums1[idx1] < nums2[idx2]) {
            return getKth(nums1, idx1 + 1, r1, nums2, l2, r2, k - (idx1 - l1 + 1));     // 排除了 idx1 - l1 + 1 个数
        }
        return getKth(nums1, l1, r1, nums2, idx2 + 1, r2, k - (idx2 - l2 + 1));         // 排除了 idx2 - l2 + 1 个数
    }
};

 

posted @ 2021-09-16 11:23  rookie_Acmer  阅读(41)  评论(0)    收藏  举报