寻找两个有序数组的中位数
思路:寻找中位数转换为寻找顺序排在中间的「最小值」是多少(两个数组总长度为双数时,寻找排在中间的两个最小值)
- step 1 首先处理两个长度各自相等的情况,该情况下,讲其中一个数组尾部追加一个 MAXINT 值用以占位(该值不会参与后续计算过程)
- 其他情况下,初始中位 n1,n2 的下标即可从较长数组中得到(n2 在单数的时候不需要管)
+-----------------+
|1|2|3|4|5|6|7|8|9|
+-----------------+
↑
↓
+-----------+
|1|2|3|3|4|4|
+-----------+
- step 2 以下标为标准,从较短数组初始位开始寻找,当值大于下标值的时候结束循环,分别根据单双的情况输出 n1,n2 的计算结果,值小于等于下标值的时候,处理下标移动,如图
··+-----------------+
|1|1|2|3|4|5|6|7|8|9|
··+-----------------+
↑
↓
+-----------+
|1|2|3|3|4|4|
+-----------+
附源码
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
var n1, n2 int
var bigpo1 int
var small, big *[]int
if len(nums1) > len(nums2) {
small = &nums2
big = &nums1
} else {
big = &nums2
small = &nums1
}
second := (len(nums1) + len(nums2)) % 2
bigpo1 = (len(nums1) + len(nums2)) / 2
if len(nums1) == len(nums2) {
*big = append(*big, math.MaxInt32)
}
n1 = (*big)[bigpo1]
if second == 0 {
if len(*big) > 1 {
n2 = (*big)[bigpo1-1]
} else {
n2 = (*small)[len(*small)-1]
}
}
for _, v := range *small {
bigpo1--
if v <= n1 {
if second == 1 {
if bigpo1 >= 0 && v < ((*big)[bigpo1]) {
n1 = ((*big)[bigpo1])
} else {
n1 = v
}
} else if v > n2 {
n1 = v
} else {
n1 = n2
if bigpo1 > 0 && v < ((*big)[bigpo1-1]) {
n2 = ((*big)[bigpo1-1])
} else {
n2 = v
}
}
} else {
break
}
}
if second == 1 {
return float64(n1)
}
return (float64(n1) + float64(n2)) / 2
}