解法一
- 先找到两个数组的长度, 然后遍历找到中位数即可
- 如果是奇数个, 那么就直接返回, 如果是偶数个, 那么就返回它与它前一个树的和的平均数
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int target = (nums1Size + nums2Size) >> 1;
int i, j, pre, res;// pre记录res前边的一个数, res为返回结果
i = j = pre = res = 0;
// 判读跳出循环是因为一个数组到尽头了还是找到中位数了
int flag = 0;
// 计数器, 找到中位数
int count = -1;
while (i < nums1Size && j < nums2Size) {
pre = res;
res = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
count++;
if (count == target) {
flag = 1;
break;
}
}
if (!flag) {
while (count != target) {
pre = res;
res = (i == nums1Size) ? nums2[j++] : nums1[i++];
count++;
}
}
return (nums1Size + nums2Size) & 1 ? res * 1.0 : (pre + res) * 1.0 / 2;
}
复杂度分析: 假设两个数组长度分别为m, n, 本算法的遍历次数为(n + m) / 2, 所以复杂度为O(m + n)
解法二
算法思想:
- 使用二分思想
- 本题相当于在两个有序数组中查找中位数, 可以使用二分方法依次排除不可能的取值
- 假设查找值为k, 那么A[0-k/2]和B[0-k/2]绝对不会是结果, 我们可以利用这个性质, 递归求得结果
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int k, flag = 0;
flag = (nums1Size + nums2Size) & 1;
if (!nums1Size) return flag ? nums2[(nums2Size >> 1)] : (nums2[(nums2Size) >> 1] + nums2[((nums2Size) >> 1) - 1]) * 1.0 / 2;
if (!nums2Size) return flag ? nums1[(nums1Size >> 1)] : (nums1[(nums1Size) >> 1] + nums1[((nums1Size) >> 1) - 1]) * 1.0 / 2;
k = flag ? ((nums1Size + nums2Size) >> 1) + 1 : ((nums1Size + nums2Size) >> 1);
int a1 = 0, a2 = 0;
while (k > 1) {
int offset = (k >> 1) - 1;
offset = a1 + offset >= nums1Size ? nums1Size - a1 - 1 : offset;
offset = a2 + offset >= nums2Size ? nums2Size - a2 - 1 : offset;
a1 += offset;
a2 += offset;
if (nums1[a1] <= nums2[a2]) {
a1 += 1;
a2 -= offset;
} else {
a1 -= offset;
a2 += 1;
}
k = k - (offset + 1);
if (a1 >= nums1Size) return flag ? nums2[a2 + k - 1] : (nums2[a2 + k - 1] + nums2[a2 + k]) * 1.0 / 2;
if (a2 >= nums2Size) return flag ? nums1[a1 + k - 1] : (nums1[a1 + k - 1] + nums1[a1 + k]) * 1.0 / 2;
}
if (flag) {
if (a1 >= nums1Size) return nums2[a2];
else if (a2 >= nums2Size) return nums1[a1];
else return nums1[a1] > nums2[a2] ? nums2[a2] : nums1[a1];
}
if (nums1[a1] > nums2[a2]) {
if (a2 + 1 >= nums2Size) return (nums1[a1] + nums2[a2]) * 1.0 / 2;
if (nums2[a2 + 1] < nums1[a1]) return (nums2[a2] + nums2[a2 + 1]) * 1.0 / 2;
return (nums1[a1] + nums2[a2]) * 1.0 / 2;
} else {
if (a1 + 1 >= nums1Size) return (nums1[a1] + nums2[a2]) * 1.0 / 2;
if (nums1[a1 + 1] < nums2[a2]) return (nums1[a1] + nums1[a1 + 1]) * 1.0 / 2;
return (nums1[a1] + nums2[a2]) * 1.0 / 2;
}
}
复杂度: 假设两个数组长度为m, n, 由于使用二分查找, 复杂度为O(log(m + n))