LeetCode04-寻找两个正序数组的中位数
4.寻找两个正序数组的中位数:
给定两个大小分别为 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
提示:
- nums1.length == m
- nums2.length == n
- 0 <= m <= 1000
- 0 <= n <= 1000
- 1 <= m + n <= 2000
- -106 <= nums1[i], nums2[i] <= 106
解题思路1:
暴力归并,时间复杂度:O(n+m)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
vector<int>tmp;
int len1=nums1.size();
int len2=nums2.size();
int i=0,j=0,k=0;
while(i<len1&&j<len2){
if(nums1[i]<=nums2[j])
tmp.push_back(nums1[i++]);
else
tmp.push_back(nums2[j++]);
}
while(i<len1)
tmp.push_back(nums1[i++]);
while(j<len2)
tmp.push_back(nums2[j++]);
double ans;
int mid=(len1+len2)>>1;
if((len1+len2)%2)
ans=tmp[mid]*1.0;
else
ans=(tmp[mid]+tmp[mid-1])*0.5;
return ans;
}
};
解题思路2:
二分,寻找两个数组的第K大,时间复杂度:O(log(n+m))
class Solution {
int find_Kth(vector<int>& nums1, vector<int>& nums2,int k){
int n=nums1.size();
int m=nums2.size();
int index1=0;
int index2=0;
while(true)
{
if(index1==n)
return nums2[index2+k-1];
if(index2==m)
return nums1[index1+k-1];
if(k==1)
return nums1[index1]<=nums2[index2]?nums1[index1]:nums2[index2];
int newindex1=index1+k/2-1;
int newindex2=index2+k/2-1;
if(newindex1>=n)
newindex1=n-1;
if(newindex2>=m)
newindex2=m-1;
if(nums1[newindex1]<=nums2[newindex2])
{
k-=newindex1-index1+1;
index1=newindex1+1;
}
else
{
k-=newindex2-index2+1;
index2=newindex2+1;
}
}
}
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n=nums1.size();
int m=nums2.size();
if((n+m)%2==0)
return (find_Kth(nums1,nums2,(n+m)/2)+find_Kth(nums1,nums2,(n+m)/2+1))*0.5;
else
return find_Kth(nums1,nums2,(n+m+1)/2);
}
};
解题思路3:
困难题,官方题解写得挺好的,传送门
数组划分,二分 (二分太难了,细节过于难扣,一定要注意边界判断条件!!!包括但不限于l和r的初始值,if、else里面的判断条件,何时更新答案)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size(),m=nums2.size();
//如果第一个数组长度要小,则需要交换
if(n>m){
return findMedianSortedArrays(nums2,nums1);
}
int i,pre_i,j,pre_j,l=0,r=n; //这里必须从n开始,因为数组划分的原因,要把第一个数组的所有数都分进去,i就必须取到n(下标从0开始)
int Median1,Median2;
while(l<=r){
int nums_i,nums_j,nums_prei,nums_prej;
int mid = (l+r)>>1;
i=mid;
j=(n+m+1)/2-i;
nums_i = (i==n) ? INT_MAX : nums1[i];
nums_j = (j==m) ? INT_MAX : nums2[j];
nums_prei = (i==0) ? INT_MIN : nums1[i-1];
nums_prej = (j==0) ? INT_MIN : nums2[j-1];
printf("%d %d %d %d %d %d\n",i,j,nums_i,nums_j,nums_prei,nums_prej);
if(nums_prei<=nums_j){
l=mid+1;
Median1 = max(nums_prei,nums_prej);
Median2 = min(nums_i,nums_j);
printf("1: %d\n",Median1);
printf("2: %d\n",Median2);
}else{
//缩小区间不能更新值答案Median,因为不符合条件
r=mid-1;
}
}
printf("%d %d\n",Median1,Median2);
return ((m+n)%2==1) ? Median1 : (Median1+Median2)/2.0;
}
};
1834

被折叠的 条评论
为什么被折叠?



