问题描述:
给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
解题思路:
题目要求时间复杂度log(n+m),首先想到二分法,而且所给数组也是有序数组,
但是此题是俩数组,所以这里要改变一下思路,查找第k大元素
对一个数组进行二分查找,因为k=(n+m)/2;
在num1中进行二分查找,假设c1为num1中点,c1=(left+right)/2,c2=(n+m)/2-c1
c1 | |||||||
c2 |
此时 c1和c2初始俩个元素的中间值上,然后判断n+m的奇偶性,得出中序元素
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
int m = nums2.size();
if (n > m) //保证数组1一定最短 //为了加快速度 对长度短的进行二分
{
return findMedianSortedArrays(nums2, nums1);
}
int LMax1 = 0, LMax2 = 0, RMin1 = 0, RMin2 = 0, c1, c2, lo = 0, hi = n;
while (lo <= hi) {
c1 = (hi + lo ) / 2;
c2 = (m + n) / 2 - c1;
LMax1 = (c1 == 0) ? INT_MIN : nums1[c1 - 1];
RMin1 = (c1 == n) ? INT_MAX : nums1[c1];
LMax2 = (c2 == 0) ? INT_MIN : nums2[c2 - 1];
RMin2 = (c2 == m) ? INT_MAX : nums2[c2];
if (LMax1 > RMin2)
hi = c1 - 1;
else if (LMax2 > RMin1)
lo = c1 + 1;
else
break;
}
if ((m + n) % 2)
return min(RMin1, RMin2);
else
return (max(LMax1, LMax2) + min(RMin1, RMin2)) / 2.0;
}
};
说明C1或C2已经到头
这种情况出现在:如果有个数组完全小于或大于中值。假定n<m, 可能有4种情况:
C1 = 0 —— 数组1整体都在右边了,所以都比中值大,中值在数组2中,简单的说就是数组1割后的左边是空了,所以我们可以假定LMax1 = INT_MIN
C1 = n —— 数组1整体都在左边了,所以都比中值小,中值在数组2中 ,简单的说就是数组1割后的右边是空了,所以我们可以假定RMin1= INT_MAX,来保证LMax2<RMin1恒成立
C2 = 0 —— 数组2整体在右边了,所以都比中值大,中值在数组1中 ,简单的说就是数组2割后的左边是空了,所以我们可以假定LMax2 = INT_MIN
C2 = m —— 数组2整体在左边了,所以都比中值小,中值在数组1中, 简单的说就是数组2割后的右边是空了,为了让LMax1 < RMin2 恒成立,我们可以假定RMin2 = INT_MAX