Leetcode - 熟能生巧 之 1 - ?
Posted 一杯敬朝阳一杯敬月光
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode - 熟能生巧 之 1 - ?相关的知识,希望对你有一定的参考价值。
目录
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,一个指向nums2,时间复杂度 O(n)。
二: 二分查找
可以将该题转换成查找两个各自有序数组的第 k 小数, help 函数就是具体执行寻找第 k 小数的函数。注意第 k 用下标表示是 k - 1。
- 二分,每次只在两个数组中看 k // 2 - 1 的数
- 若 nums1[k // 2 - 1] <= nums2[k // 2 - 1],则 nums1[new_idx1] 小的最多只有 nums1 的前 k // 2 - 1 个数和 nums2 的前 k // 2 - 1 个数,即比 nums1[new_idx1] 小的最多 k - 2 个数,即第 k 小的数 不存在于 nums1[new_idx1] 或 nums2[new_idx2] 之前,且 nums1[new_idx1] 最多是第 k - 1 小的数,所以我们可以排除掉 nums1[new_idx1] 及其之前的,还有 nums2[new_idx2] 之前的,但是 nums2[new_idx2] 待定,所以 new_idx1 右移 1, k 相应变化
- 若 nums1[k // 2 - 1] > nums2[k // 2 - 1],思路同上。
- 推出条件,当有一个数组已经遍历完毕,则第 k 小数只会出现在另一个数组,可以轻易求出,这边 -1,是因为第 k 小数折算成下标需要减一;另一种可退出情况是,两个数组都有值,但是 k = 1,这个时候也能轻易求出,两者谁最小取谁。
class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
# 寻找第k大数
def help1(idx1, idx2, k):
if idx1 == m:
return nums2[k + idx2 - 1]
if idx2 == n:
return nums1[k + idx1 - 1]
if k == 1:
return min(nums1[idx1], nums2[idx2])
new_idx1 = min(m - 1, k // 2 - 1 + idx1)
new_idx2 = min(n - 1, k // 2 - 1 + idx2)
p1, p2 = nums1[new_idx1], nums2[new_idx2]
if p1 <= p2:
k -= new_idx1 - idx1 + 1
return help1(new_idx1 + 1, idx2, k)
else:
k -= new_idx2 - idx2 + 1
return help1(idx1, new_idx2 + 1, k)
def help(k):
idx1, idx2 = 0, 0
while True:
if idx1 == m:
return nums2[k + idx2 - 1]
if idx2 == n:
return nums1[k + idx1 - 1]
if k == 1:
return min(nums1[idx1], nums2[idx2])
new_idx1 = min(m - 1, k // 2 - 1 + idx1)
new_idx2 = min(n - 1, k // 2 - 1 + idx2)
p1, p2 = nums1[new_idx1], nums2[new_idx2]
if p1 <= p2:
k -= (new_idx1 - idx1 + 1)
idx1 = new_idx1 + 1
else:
k -= (new_idx2 - idx2 + 1)
idx2 = new_idx2 + 1
m, n = len(nums1), len(nums2)
length = m + n
one = help1(0, 0, (length + 1) // 2)
# one = help((length + 1) // 2)
if length % 2 == 1:
return one
else:
# return (one + help(length // 2 + 1)) * 1. / 2
return (one + help1(0, 0, length // 2 + 1)) * 1. / 2
以上是关于Leetcode - 熟能生巧 之 1 - ?的主要内容,如果未能解决你的问题,请参考以下文章