问题
给定两个大小分别为m和n的正序(从小到大)数组nums1和nums2。请你找出并返回这两个正序数组的中位数。
示例 1: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2
示例 2: 输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3: 输入:nums1 = [0,0], nums2 = [0,0] 输出:0.00000
示例 4: 输入:nums1 = [], nums2 = [1] 输出:1.00000
示例 5: 输入:nums1 = [2], nums2 = [] 输出:2.00000
方法1
- 正常排序数组的中位数计算
- 数组长度
len%2==0,返回中间两个数的平均数 - 数组长度
len%2!=0,返回中间的数
- 数组长度
- 特殊情况,两个数组的其中一个为空,直接调用
double findMedianSortedArrays(vector<int> &nums) - (直接思路)两个数组已经有序,可以选择直接合并,合并完成后计算中位数
时间复杂度:,空间复杂度:
class Solution {public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int len1=nums1.size();int len2=nums2.size();if(len1==0){return findMedianSortedArrays(nums2);}else if(len2==0){return findMedianSortedArrays(nums1);}else{vector<int> nums;int i=0,j=0;while(i<len1&&j<len2){if(nums1[i]<nums2[j]){nums.push_back(nums1[i]);i++;}else{nums.push_back(nums2[j]);j++;}}while(i<len1){nums.push_back(nums1[i]);i++;}while(j<len2){nums.push_back(nums2[j]);j++;}return findMedianSortedArrays(nums);}}double findMedianSortedArrays(vector<int> &nums){int len=nums.size();if(len%2==0){return (nums[len/2-1]+nums[len/2])*1.0/2;}else{return nums[len/2]*1.0;}}};
方法2
Note: 排序数组问题在限定时间复杂度的情况下, 一般都可以使用二分法解决.
假设两个有序数组分别是和
。要找到第
个元素,我们可以比较
和
。由于
和
的前面分别有
和
,即
个元素,对于
和
中的较小值,最多只会有
个元素比它小,那么它就不能是第
小的数了。
因此可以归纳出三种情况:
- 如果
,则比
小的数最多只有
的前
个数和
的前
个数,即比
小的数最多只有
个,因此
不可能是第
个数,
到
也都不可能是第
个数,可以全部排除。
- 如果
,则可以排除
到
。
如果
,则可以归入第一种情况处理。
class Solution {public:int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k) {int m = nums1.size();int n = nums2.size();int index1 = 0, index2 = 0;while (true) {// 边界情况if (index1 == m) {return nums2[index2 + k - 1];}if (index2 == n) {return nums1[index1 + k - 1];}if (k == 1) {return min(nums1[index1], nums2[index2]);}// 正常情况int newIndex1 = min(index1 + k / 2 - 1, m - 1);int newIndex2 = min(index2 + k / 2 - 1, n - 1);int pivot1 = nums1[newIndex1];int pivot2 = nums2[newIndex2];if (pivot1 <= pivot2) {k -= newIndex1 - index1 + 1;index1 = newIndex1 + 1;}else {k -= newIndex2 - index2 + 1;index2 = newIndex2 + 1;}}}double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int totalLength = nums1.size() + nums2.size();if (totalLength % 2 == 1) {return getKthElement(nums1, nums2, (totalLength + 1) / 2);}else {return (getKthElement(nums1, nums2, totalLength / 2) + getKthElement(nums1, nums2, totalLength / 2 + 1)) / 2.0;}}};
