寻找两个正序数组的中位数 - 二分 1
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
n, m := len(nums1), len(nums2)
left := (n + m + 1) >> 1
right := (n + m + 2) >> 1
if left == right { // odd
return float64(getKth(nums1, nums2, left))
}
// even
return (float64(getKth(nums1, nums2, left)) + float64(getKth(nums1, nums2, right))) / 2
}
// 获取第 k 小的数
func getKth(nums1, nums2 []int, k int) int {
len1, len2 := len(nums1), len(nums2)
//让 len1 的长度小于 len2,这样就能保证如果有数组空了,一定是 len1
if len1 > len2 {
return getKth(nums2, nums1, k)
}
if len1 == 0 {
return nums2[k - 1]
}
if k == 1 {
return min(nums1[0], nums2[0])
}
idx1 := min(len1, k >> 1)
idx2 := min(len2, k >> 1)
if nums1[idx1 - 1] > nums2[idx2 - 1] {
return getKth(nums1, nums2[idx2:], k - idx2)
}
return getKth(nums1[idx1:], nums2, k - idx1)
}
寻找两个正序数组的中位数 - 二分 2
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
n, m := len(nums1), len(nums2)
if m < n { // 保证 nums1 不长于 nums2
n, m = m, n
nums1, nums2 = nums2, nums1
}
iMin, iMax := 0, n
for iMin <= iMax {
i := iMin + (iMax - iMin) >> 1
// i + j = n - i + m - j
j := (n + m + 1) >> 1 - i
if j > 0 && i < n && nums2[j - 1] > nums1[i] { // i 需要增大
iMin = i + 1
} else if i > 0 && j < m && nums1[i - 1] > nums2[j] { // i 需要减小
iMax = i - 1
} else {
maxLeft := 0
if i == 0 {
maxLeft = nums2[j - 1]
} else if j == 0 {
maxLeft = nums1[i - 1]
} else {
maxLeft = max(nums1[i - 1], nums2[j - 1])
}
if (n + m) & 1 == 1 { // odd
return float64(maxLeft)
}
minRight := 0
if i == n {
minRight = nums2[j]
} else if j == m {
minRight = nums1[i]
} else {
minRight = min(nums1[i], nums2[j])
}
// even
return (float64(maxLeft) + float64(minRight)) / 2
}
}
return 0
}