ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
题目链接
题目大意:从俩个排序好的数组里找到这两个数组的中位数,时间复杂度为 O(log (m+n)),m,n为两数组长度
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
为什么i是在小的数组里呢?因为如果i是在大的数组里的话,那么算出来的j可能会是负数。
博主刚学c++代码写得很差
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
vector<int> A = nums1;
vector<int> B = nums2;
// 交换数组,A为长度小的数组,B为长度大的数组
if(A.size() > B.size()){
vector<int> t = B;
B = A;
A = t;
}
int n = A.size(), m = B.size();
if(n==0){
if(m%2==1){
return (double)B[(m-1)/2];
}else{
return (double)(B[(m-1)/2] + B[(m-1)/2+1])/2.0;
}
}
int iMin = 0;
int iMax = n;
double LMAX = 0, RMIN = 0;
// 二分查找i
while(iMin <= iMax){
int i = iMin + (iMax-iMin)/2;
int j = (m+n+1)/2-i;
// 存在临界情况即一整个数组在一边
if((i==n || j==0 || A[i]>=B[j-1])
&& (j==m || i==0 || B[j]>=A[i-1])){
if(i==0){
LMAX = B[j-1];
}else if(j==0){
LMAX = A[i-1];
}else{
LMAX = max(A[i-1], B[j-1]);
}
if(i==n){
RMIN = B[j];
}else if(j==m){
RMIN = A[i];
}else{
RMIN = min(A[i], B[j]);
}
break;
}else if(i>0 && A[i-1] > B[j]){
iMax = i-1;
}else if(j>0 && B[j-1] > A[i]){
iMin = i+1;
}
}
if((n+m)%2==0){
return (double)(LMAX+RMIN)/2.0 ;
}else{
return LMAX;
}
}
};
二进制问题half = (iMin+iMax)/2 == iMin + (iMax-iMin)/2 == iMin&iMax + (iMin^iMax)>>1;
可以理解过iMax和iMin的和为n, n的一半等于 a + (b-a)/2 (a+b==n, && a<=b)
举个例子a+b=9, 4 == 9/2 == 2+(7-2)/2 == 1+(8-1)/2 == 3+(6-3)/2
iMin&&iMax + (iMin^iMax)>>1 的原理差不多就是这样。
一份23ms的优秀提交(别人的)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
if (m > n) return findMedianSortedArrays(nums2, nums1);
int i, j, imin = 0, imax = m, half = (m + n + 1) / 2;
while (imin <= imax) {
i = (imin & imax) + ((imin ^ imax) >> 1);
j = half - i;
if (i > 0 && j < n && nums1[i - 1] > nums2[j]) imax = i - 1;
else if (j > 0 && i < m && nums2[j - 1] > nums1[i]) imin = i + 1;
else break;
}
int num1;
if (!i) num1 = nums2[j - 1];
else if (!j) num1 = nums1[i - 1];
else num1 = max(nums1[i - 1], nums2[j - 1]);
if ((m + n) & 1) return num1;
int num2;
if (i == m) num2 = nums2[j];
else if (j == n) num2 = nums1[i];
else num2 = min(nums1[i], nums2[j]);
return (num1 + num2) / 2.0;
}
};
// 加上这个可以提高io速度
static const auto _____ = []()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();