LeetCode 每日一题 4. 寻找两个正序数组的中位数

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路比较简单,在两个数组中分别二分,找在两数组中排位大于等于 k 的位置。

#pragma GCC optimize("O2")
#pragma G++ optimize("O2")

#include <bits/stdc++.h>

using namespace std;
class Solution {
 public:
  double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    int n = nums1.size() + nums2.size();
    if(n & 1)
      return findNthElementSortedArrays(nums1, nums2, n / 2);
    return (findNthElementSortedArrays(nums1, nums2, n / 2 - 1) + findNthElementSortedArrays(nums1, nums2, n / 2)) / 2.0;
  }

 private:
  double findNthElementSortedArrays(vector<int>&nums1, vector<int>&nums2, const int k)const {
    int len = nums1.size();
    int first = 0;
    int midVal, half;

    if(nums1.size() > 0) {
      while(len > 0) {
        half = len >> 1;
        midVal = nums1[first + half];
        int posLeft = (lower_bound(nums1.begin(), nums1.end(), midVal) - nums1.begin())
                      + (lower_bound(nums2.begin(), nums2.end(), midVal) - nums2.begin());

        int posRight = (upper_bound(nums1.begin(), nums1.end(), midVal) - nums1.begin())
                       + (upper_bound(nums2.begin(), nums2.end(), midVal) - nums2.begin());
        //cout << midVal << " " << posLeft << " " << posRight <<endl;
        if(posLeft <= k && posRight > k)
          return midVal;
        if(posRight <= k)
          len = len - 1 - half, first += half + 1;
        else
          len = half;
      }
    }

    len = nums2.size();
    first = 0;
    if(nums2.size() > 0) {
      while(len > 0) {
        half = len >> 1;
        midVal = nums2[first + half];
        int posLeft = (lower_bound(nums1.begin(), nums1.end(), midVal) - nums1.begin())
                      + (lower_bound(nums2.begin(), nums2.end(), midVal) - nums2.begin());

        int posRight = (upper_bound(nums1.begin(), nums1.end(), midVal) - nums1.begin())
                       + (upper_bound(nums2.begin(), nums2.end(), midVal) - nums2.begin());
        if(posLeft <= k && posRight > k)
          return midVal;
        if(posRight <= k)
          len = len - 1 - half, first += half + 1;
        else
          len = half;
      }
    }
    return 0;
  }
};

原文地址:https://www.cnblogs.com/Forgenvueory/p/12956618.html