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 个数 } };