[LeetCode-Golang] 4. 寻找两个有序数组的中位数
题目
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
将题目转化为求两个有序数组第k小的数。每次删掉前k/2个数,更新k
参考https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/中的解法三
复杂度分析
时间复杂度O(log(m + n))
空间复杂度O(1) 虽然用了递归,但是是尾递归,所以仍为O(1)
代码
func findMedianSortedArrays(nums1 []int, nums2 []int) float64 { sumLen := len(nums1) + len(nums2) if sumLen & 1 == 1 { // 总长为奇数 return float64(findKth(nums1, nums2, (sumLen+1)>>1)) } else { // 总长为偶数 return float64(findKth(nums1, nums2, sumLen>>1) + findKth(nums1, nums2,(sumLen>>1)+1)) * 0.5 } } func findKth(nums1, nums2 []int, k int) int { len1 := len(nums1) len2 := len(nums2) // 设置nums1为短切片 if len1 > len2 { return findKth(nums2, nums1, k) } // 如果nums1已经到末尾,直接返回nums2的第k-1个元素 if len1 == 0 { return nums2[k-1] } // 如果k==1,只要判断两个切片的第0个元素,取最小值 if k == 1 { return minInt(nums1[0], nums2[0]) } // 找到两个切片的第k/2-1个元素,比较大小。注意len(nums1)可能小于k/2 pos1 := minInt(len1, k>>1) - 1 pos2 := k>>1 -1 if nums1[pos1] < nums2[pos2] { // 删除nums1的前pos1个元素 return findKth(nums1[pos1+1:], nums2, k - pos1 -1) } return findKth(nums1, nums2[pos2+1:], k - pos2 -1) } func minInt(a, b int) int { if a < b { return a } return b }
执行结果
执行用时 :8 ms, 在所有 Go 提交中击败了99.63% 的用户
内存消耗 :5.6 MB, 在所有 Go 提交中击败了100.00%的用户