[Leetcode][4. 寻找两个正序数组的中位数] 4种方法:合并数组,二分搜索,划分数组
By Long Luo
Leetcode 4. 寻找两个正序数组的中位数 ,这是一道很经典的题目,非常考察算法功底和逻辑思维能力,下面我们就通过几种解法来吃透这道题吧!
方法一:暴力法(合并数组)
思路与算法:
很直观的解法,先将两个数组按照元素大小合并为一个数组,然后根据新数组长度来决定返回值。
注意在合并数组时,要注意指针边界情况,不要越过数组边界。
代码如下所示: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
38public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
if (m == 0) {
if (n % 2 == 0) {
return (nums2[n / 2 - 1] + nums2[n / 2]) / 2.0;
} else {
return nums2[n / 2];
}
} else if (n == 0) {
if (m % 2 == 0) {
return (nums1[m / 2 - 1] + nums1[m / 2]) / 2.0;
} else {
return nums1[m / 2];
}
}
int[] nums = new int[m + n];
int total = m + n;
for (int i = 0, j = 0, cnt = 0; cnt < total; ) {
if (i == m && j < n) {
nums[cnt++] = nums2[j++];
} else if (j == n && i < m) {
nums[cnt++] = nums1[i++];
} else if (i < m && nums1[i] <= nums2[j]) {
nums[cnt++] = nums1[i++];
} else if (i < m && nums1[i] > nums2[j]) {
nums[cnt++] = nums2[j++];
}
}
if (total % 2 == 0) {
return (nums[total / 2 - 1] + nums[total / 2]) / 2.0;
} else {
return nums[total / 2];
}
}
其实,在合并数组时,实际上只需要合并到 \(cnt=total/2\) 即可,优化之后如下所示: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
38public double findMedianSortedArrays_bf_opt(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
if (m == 0) {
if (n % 2 == 0) {
return (nums2[n / 2 - 1] + nums2[n / 2]) / 2.0;
} else {
return nums2[n / 2];
}
} else if (n == 0) {
if (m % 2 == 0) {
return (nums1[m / 2 - 1] + nums1[m / 2]) / 2.0;
} else {
return nums1[m / 2];
}
}
int[] nums = new int[m + n];
int total = m + n;
for (int i = 0, j = 0, cnt = 0; cnt <= total / 2; ) {
if (i == m && j < n) {
nums[cnt++] = nums2[j++];
} else if (j == n && i < m) {
nums[cnt++] = nums1[i++];
} else if (i < m && nums1[i] <= nums2[j]) {
nums[cnt++] = nums1[i++];
} else if (i < m && nums1[i] > nums2[j]) {
nums[cnt++] = nums2[j++];
}
}
if (total % 2 == 0) {
return (nums[total / 2 - 1] + nums[total / 2]) / 2.0;
} else {
return nums[total / 2];
}
}
复杂度分析:
- 时间复杂度:\(O(m+n)\),需要遍历 \(2\) 个数组。
- 空间复杂度:\(O(m+n)\),开辟了一个新数组,长度为 \(m+n\)。