4. 寻找两个正序数组的中位数(找第K小数)
作者:互联网
1.Description
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
2.Example
示例 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.My Code(投机取巧)
使用merge之前需要先指定好目标vector的size,才能够merge操作;取中位数要乘1.0转为浮点数
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
vector<int>nums3(nums1.size()+nums2.size());
merge(nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),nums3.begin());
sort(nums3.begin(),nums3.end());
if(nums3.size()%2==1)
return nums3[nums3.size()/2];
return (nums3[nums3.size()/2]*1.0 + nums3[nums3.size()/2-1]*1.0)/2;
}
};
4.Code(正解)
难度主要在于实现O(log(m+n))的复杂度,使用查找第K个数的思想,注意边界情况。
复杂度的要求有log的,通常都需要用到二分查找,这道题也可以通过二分查找实现。
#include<algorithm>
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n1 = nums1.size();
int n2 = nums2.size();
if((n1+n2)%2==1)
return findKthNum(nums1,nums2,(n1+n2)/2+1);
return (findKthNum(nums1,nums2,(n1+n2)/2+1)*1.0 + findKthNum(nums1,nums2,(n1+n2)/2)*1.0)/2;
}
//这是里的k是从1算起,就是找第k小的数
int findKthNum(vector<int>& nums1, vector<int>& nums2,int k){
int idx1=0,idx2=0;
int len1 = nums1.size();
int len2 = nums2.size();
while(true){
//边界问题
//选取两个数组剩余元素的第一个中最小的
if(k==1)
return min(nums1[idx1],nums2[idx2]);
//nums1已经没有元素可以删除了
if(nums1.size() == idx1)
return nums2[idx2+k-1];
if(nums2.size() == idx2)
return nums1[idx1+k-1];
//递增idx1,idx2,进行元素删除
int index1 = min(len1 -1,idx1 + k/2 -1);
int index2 = min(len2 -1,idx2 + k/2-1);
if(nums1[index1]>=nums2[index2]){
k -= index2 - idx2+1;
idx2 = index2 +1;
}else{
k -= index1 - idx1+1;
idx1 = index1 +1;
}
}
}
};
5.思路
1.注意:这里的K一直都是从1算起的(nums[0]为第1小的元素),每次需要比较的是nums[index + k/2 -1],需要注意是否会数组越界。
2.三种边界情况需要注意。
3. 注意:在如min(nums.size(),k/2)中,会提示找不到对应的min函数,因为这里nums.size()为size_type类型,需要转化为int类型才能够使用min函数来对比。
标签:正序,int,nums3,中位数,idx2,小数,nums1,nums2,size 来源: https://blog.csdn.net/badmer/article/details/123108365