LeetCode-4

概述

作为复杂题的第一题(Median of Two Sorted Arrays),在时间复杂度为O(log (m+n))
mn均为数组长度)的要求之下,求两个已排序数组的中位数。

分析

首先中位数的定义可以在 WikiPedia 上了解到。在已排序的前提下,即奇数元素个数的数组,为中间值;偶数元素个数的数组则为中间二值的算数平均数。

那么两个序列求中位数,可以考虑先将二者合并排序之后,进行中位数的求值。

考虑到两数组已经排序,那么我们所需要做的就是进行一次归并排序。

归并排序作为一个相当稳定的排序方式,在时间复杂度上能够满足需求。

考虑到虽然数组是排序数组,但是并没有说明是升序或是降序,无妨,如果是降序,那么将下标从尾部开始即可,但是个人测试,应该没有出现这类 case 。

解法

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public class Solution {
private static final int ASC = 0;
private static final int DESC = 1;

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
double median = 0;

if (nums1.length + nums2.length == 0) {
return 0;
}

if (nums1.length == 1 && nums2.length == 1) {
return (nums1[0] + nums2[0]) / 2.0;
}

int[] mergedNums = new int[nums1.length + nums2.length];

int i = 0;
int j = 0;
int nums1order = (nums1.length >= 2 && nums1[0] > nums1[1]) ? DESC : ASC;
int nums2order = (nums2.length >= 2 && nums2[0] > nums2[1]) ? DESC : ASC;
int mergedIdx = 0;

for (;i < nums1.length || j < nums2.length;) {
int realI = i;
int realJ = j;

if (i >= nums1.length) {
mergedNums[mergedIdx] = nums2[realJ];
++j;
++mergedIdx;
continue;
}

if (j >= nums2.length) {
mergedNums[mergedIdx] = nums1[realI];
++mergedIdx;
++i;
continue;
}

int iVal = nums1[realI];
int jVal = nums2[realJ];

if (iVal == jVal) {
mergedNums[mergedIdx] = iVal;
++mergedIdx;
mergedNums[mergedIdx] = jVal;
++mergedIdx;
++i;
++j;
continue;
}

if (iVal > jVal) {
mergedNums[mergedIdx] = jVal;
++mergedIdx;
++j;
continue;
}

if (iVal < jVal) {
mergedNums[mergedIdx] = iVal;
++mergedIdx;
++i;
}
}

int mergedSize = mergedNums.length;
int medianIdx = (mergedSize + 1) / 2 - 1;

if (mergedSize % 2 == 1) {
median = mergedNums[medianIdx];
} else {
medianIdx = mergedIdx / 2;
median = (mergedNums[medianIdx] + mergedNums[medianIdx - 1]) / 2.0;
}

return median;
}
}