持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
题目描述
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入: nums1 = [1,3], nums2 = [2]
输出: 2.00000
解释: 合并数组 = [1,2,3] ,中位数 2
示例 2:
输入: nums1 = [1,2], nums2 = [3,4]
输出: 2.50000
解释: 合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
nums1.length == mnums2.length == n0 <= m <= 10000 <= n <= 10001 <= m + n <= 2000-106 <= nums1[i], nums2[i] <= 106
解题思路
- 两个有序数组查找中位数。最简单的直接将两数组合并,然后排序,输出中位数.但是排序时间复杂度为O(nlogn)。优化一下,可以用双指针去将两数组合并为一个数组,合并到中位数那个位置就可以输出了.复杂度**O(n)**解题是完全OK。的
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
l1, l2 := len(nums1), len(nums2)
k := (l1+l2)/2 + 1
l1, l2 = 0, 0
a := make([]int, 0)
for i := 0; i < k; i++ {
if l1 < len(nums1) {
if l2 < len(nums2) {
if nums1[l1] < nums2[l2] {
a = append(a, nums1[l1])
l1 += 1
} else {
a = append(a, nums2[l2])
l2 += 1
}
} else {
a = append(a, nums1[l1])
l1 += 1
}
} else {
a = append(a, nums2[l2])
l2 += 1
}
}
if (len(nums1)+len(nums2))%2 == 0 {
return float64(a[k-1]+a[k-2]) / 2.0
} else {
return float64(a[k-1])
}
}
- 这还没上大招就99%了下面我们来讨论一下log级别的算法:
- 写一个函数,获取两数组第k小数。直接看两数组k/2的数,数组1的k/2的数小于数组2的k/2的数,数组1k/2左边的数可以直接排除,反之同理。
- 注意各种边界😅😅
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {
l := len(nums1) + len(nums2)
if l%2 == 1 {
return float64(getk(nums1, nums2, 0, 0, l/2+1))
} else {
a, b := float64(getk(nums1, nums2, 0, 0, l/2)), float64(getk(nums1, nums2, 0, 0, l/2+1))
return (a + b) / 2
}
}
func getk(nums1 []int, nums2 []int, l1, l2, k int) int {
//控制第一个数组长度小于第二个
if len(nums1)-l1 > len(nums2)-l2 {
return getk(nums2, nums1, l2, l1, k)
}
//k=1,直接返回最小数
if k == 1 {
if len(nums1) == l1 {
return nums2[l2]
} else {
return min(nums1[l1], nums2[l2])
}
}
// 第一个数组没有,直接返回第二个数组
if len(nums1) == l1 {
return nums2[l2+k-1]
}
m1, m2 := min(len(nums1), l1+k/2), l2+k-k/2
// 判断+递归
if nums1[m1-1] > nums2[m2-1] {
return getk(nums1, nums2, l1, m2, k-(m2-l2))
} else if nums1[m1-1] < nums2[m2-1] {
return getk(nums1, nums2, m1, l2, k-(m1-l1))
} else {
return nums1[m1-1]
}
}
func min(a, b int) int {
if a < b {
return a
} else {
return b
}
}
- 因为数据量太小,时间没有拉开差距,但是没有占用额外空间