题目描述

原题

Description:

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)).

You may assume nums1 and nums2 cannot be both empty.

Example 1:

Input:

nums1 = [1, 3]
nums2 = [2]

Output: 2.0
Explanation: The median is 2.0.

Example 2:

Input:

nums1 = [1, 2]
nums2 = [3, 4]

Output: 2.5
Explanation: The median is (2 + 3)/2 = 2.5

原题翻译

描述

有两个有序的数组nums1和nums2,长度分别为m和n。

找到两个排序数组的中位数。总运行时间复杂度应为O(log(m + n))。

您可以假设nums1和nums2不能都为空。

例1:

输入:

nums1 = [1, 3]
nums2 = [2]

输出:2.0
解释:[1, 2, 3]的中位数为2.0

例2:

输入:

nums1 = [1, 2]
nums2 = [3, 4]

输出:2.5
解释:[1, 2, 3, 4]的中位数为(2 + 3) / 2 = 2.5

解法一(mine)

主要思想

首尾指针法,分别为两数组设置两个指针

运行速度:超过了99.97%的解答。

内存使用:超过了89.58%的解答。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = 0, n = nums2.length - 1;
if (nums1.length == 0) {
while (n - m > 1) {
m++;
n--;
}
return (m == n) ?
(double)nums2[m] : ((double)nums2[m] + (double)nums2[n]) / 2;
}

int j = 0, k = nums1.length - 1;
if (nums2.length == 0) {
while (j < k) {
j++;
k--;
}
return (j == k) ?
(double)nums1[j] : ((double)nums1[j] + (double)nums1[k]) / 2;
}

while ((k - j) + (n - m) > 0) {
/* 这里使用了一个知识点:
* || 运算符:如果该运算符前面的条件为true,后面的条件不计算
* && 运算符:如果该运算符前面对条件为false,后面的条件不计算
*/
if (m == nums2.length || (j != nums1.length && nums1[j] < nums2[m])) {
j++;
} else if (j == nums1.length || nums1[j] >= nums2[m]){
m++;
}
// 上面的if-else语句也可以写成这样:
// if (m == nums2.length)
//     j++;
// else if (j == nums1.length)
// m++;
// else if (nums1[j] < nums2[m])
// j++;
// else if (nums1[j] >= nums2[m])
// m++;

if (k == -1 || (n != -1 && nums1[k] < nums2[n])) {
n--;
} else if (n == -1 || nums1[k] >= nums2[n]){
k--;
}
}
if (j > k)
return ((double)nums2[m] + (double)nums2[n]) / 2;
if (m > n)
return ((double)nums1[j] + (double)nums1[k]) / 2;
return ((double)nums1[j] + (double)nums2[m]) / 2;
}
}

解法二

第一名的答案。这道题的难度不亏为最高的Hard,活活研究了两天才能勉强看懂。

运行速度:超过了99.97%的解答。

内存使用:超过了84.03%的解答。

主要思想

解题思路
解题思路

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class Solution {
public double findMedianSortedArrays(int[] A, int[] B) {
int m = A.length;
int n = B.length;
if (m > n) { // 保证m<=n
int[] temp = A;
A = B;
B = temp;
int tmp = m;
m = n;
n = tmp;
}
int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
while (iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = halfLen - i;
if (i < iMax && B[j-1] > A[i]){
// i is too small
iMin = i + 1;
} else if (i > iMin && A[i-1] > B[j]) {
// i is too big
iMax = i - 1;
} else {
// i is perfect
int maxLeft = 0;
if (i == 0) {
maxLeft = B[j-1];
} else if (j == 0) {
maxLeft = A[i-1];
} else {
maxLeft = Math.max(A[i-1], B[j-1]);
}
if ((m + n) % 2 == 1) {
return maxLeft;
}
int minRight = 0;
if (i == m) {
minRight = B[j];
} else if (j == n) {
minRight = A[i];
} else {
minRight = Math.min(B[j], A[i]);
}
return (maxLeft + minRight) / 2.0;
}
}
return 0.0;
}
}