题目:
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。 nums1 = [1, 3] nums2 = [2] 则中位数是 2.0
解题思路一:直接将两个数组合并成一个数组,然后进行寻找。
注意:进行数组的判空,数组长度奇偶判断。
代码:
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int l1 = nums1.length;
int l2 = nums2.length;
int sum = l1 + l2;
int x = 0, y = 0, count = 0;
double id = 0.0;
int[] num3 = new int[sum];
if (l1 == 0) {
if (l2 % 2 == 0) {
id = (nums2[l2 / 2] + nums2[l2 / 2 - 1]) / 2.0;
} else {
id = nums2[l2 / 2];
}
}
if (l2 == 0) {
if (l1 % 2 == 0) {
id = (nums1[l1 / 2] + nums1[l1 / 2 - 1]) / 2.0;
} else {
id = nums1[l1 / 2];
}
}
while (count != sum) {
if (x == l1) {
while (y != l2) {
num3[count++] = nums2[y++];
}
break;
}
if (y == l2) {
while (x != l1) {
num3[count++] = nums1[x++];
}
break;
}
if (nums1[x] < nums2[y]) {
num3[count++] = nums1[x++];
} else {
num3[count++] = nums2[y++];
}
}
if (count % 2 == 0) {
id = (num3[sum / 2] + num3[sum / 2 - 1]) / 2.0;
} else {
id = num3[sum / 2];
}
return id;
}
}
解题思路二:没有必要将两个数组真的合并,可以象征性的进行整合计算。
代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int l1 = nums1.length;
int l2 = nums2.length;
int sum = l1 + l2;
double id = 0.0;
int right = -1, left = -1;
int aStart = 0;
int bStart = 0;
for (int i = 0; i <= sum / 2; i++) {
left = right;
if (aStart < l1 && (bStart >= l2 || nums1[aStart] < nums2[bStart])) {
right = nums1[aStart++];
} else {
right = nums2[bStart++];
}
}
if ((sum & 1) == 0) {
id = (right + left) / 2.0;
} else {
id = right;
}
return id;
}
}
解题思路三:以上两个解法都没有将时间复杂度达到O(log(m+n))的水平。递归,利用二分查找可以达到。
代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int l1 = nums1.length;
int l2 = nums2.length;
int sum = l1 + l2;
int halfLen = (sum + 1) / 2;
double id = 0.0;
if (l1 > l2) {
int[] temp = nums1;
nums1 = nums2;
nums2 = temp;
int tmp = l1;
l1 = l2;
l2 = tmp;
}
int max = l1;
int min = 0;
while (min <= max) {
int i = (min + max) / 2;
int j = halfLen - i;
if (i < max && nums2[j - 1] > nums1[i]) {
min = i + 1;
}
else if (i > min && nums1[i - 1] > nums2[j]) {
max = i - 1;
} else {
int left = 0;
if (i == 0) {
left = nums2[j - 1];
} else if (j == 0) {
left = nums1[i - 1];
} else {
left = Math.max(nums1[i - 1], nums2[j - 1]);
}
if (sum % 2 != 0) {
return left;
}
int right = 0;
if (i == l1) {
right = nums2[j];
} else if (j == l2) {
right = nums1[i];
} else {
right = Math.min(nums1[i], nums2[j]);
}
return (left + right) / 2.0;
}
}
return 0.0;
}
}