原文地址:Go-Leecode-寻找两个正序数组的中位数(刷题记录)
给定两个长度分别为m、n的正序(从小到大)数组num1和num2,需找出两个正序数组的中位数。
示例一:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
示例二:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
示例三:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例四:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例五:
输入:nums1 = [2], nums2 = []
输出:2.00000
提示内容如下:
-
nums1.length == m。
-
nums2.length == n。
-
0 <= m <= 1000。
-
0 <= n <= 1000。
-
1 <= m + n <= 2000。
-
-106 <= nums1[i], nums2[i] <= 106。
从上述示例中分析,当获取到两个正序数组num1和num2时,首先应该做的就是将num1和num2进行合并,之后计算合并后数组的位数,是奇数则取中间的元素,是偶数则取中间两数之和的二分之一。
针对以上分析,现给出解决方案一:
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
res := merge(nums1, nums2)
n := len(res)
if n == 0 {
return -1
}
if n%2 == 0 {
return float64(res[n/2-1]+res[n/2]) / 2
}
return float64(res[n/2])
}
func merge(nums1, nums2 []int) []int {
n1, n2 := len(nums1), len(nums2)
i, j := 0, 0
res := make([]int, 0, n1+n2)
for i < n1 && j < n2 {
switch {
case nums1[i] < nums2[j]:
res = append(res, nums1[i])
i++
case nums1[i] > nums2[j]:
res = append(res, nums2[j])
j++
default:
res = append(res, nums1[i], nums2[j])
i++
j++
}
}
if i < n1 {
res = append(res, nums1[i:]...)
}
if j < n2 {
res = append(res, nums2[j:]...)
}
return res
}
在网上还找到另外一种类二分查找分而治之的方案,在两个有序数组中查找第k大的数,即nums中索引为k-1的数,在舍弃区域比较值时都要-1处理。
解决方案二:
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
n1, n2 := len(nums1), len(nums2)
if n1+n2 == 0 {
return -1
}
if (n1+n2)%2 == 0 {
l := findKth(nums1, nums2, (n1+n2)/2)
r := findKth(nums1, nums2, (n1+n2)/2+1)
return float64(l+r) / 2
}
return float64(findKth(nums1, nums2, (n1+n2)/2+1))
}
func findKth(nums1, nums2 []int, k int) int {
n1, n2 := len(nums1), len(nums2)
if n1 > n2 {
n1, n2 = n2, n1
nums1, nums2 = nums2, nums1
}
if n1 == 0 {
return nums2[k-1]
}
if k == 1 {
return min(nums1[0], nums2[0])
}
k1 := min(k/2, n1)
k2 := k - k1
switch {
case nums1[k1-1] < nums2[k2-1]:
return findKth(nums1[k1:], nums2, k2)
case nums1[k1-1] > nums2[k2-1]:
return findKth(nums1, nums2[k2:], k1)
default:
return nums1[k1-1]
}
}
实话实讲,第二种方案真心没看明白。
至此,本次分享就结束了,后期会慢慢补充。
以上仅为个人观点,不一定准确,能帮到各位那是最好的。
好啦,到这里本文就结束了,喜欢的话就来个三连击吧。
扫码关注公众号,获取更多优质内容。