問題描述:
給定兩個大小爲 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