LeetCode Everyday:坚持价值投资,做时间的朋友!!!
题目:
给定两个大小为 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
代码
方法一: 暴力法,合并两个数组,进行排序,然后求中位数。
Tips: 这种方法时间复杂度取决于排序方法,可以参考我的一些笔记 快速排序
O
(
(
m
+
n
)
l
o
g
(
m
+
n
)
)
O((m+n)log(m+n))
O((m+n)log(m+n))。
本题的话时间复杂度不满足要求,只提供思路,另外,之所以编译通过,是因为验证集合维度过小。
另外python默认排序算法是Timesort算法wiki,CSDN博客翻译
执行用时 :60 ms, 在所有 Python3 提交中击败了47.66%的用户
内存消耗 :13.9 MB, 在所有 Python3 提交中击败了6.15%的用户
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
nums = nums1 + nums2
nums.sort()
i = len(nums) // 2
j = len(nums) // 2 - int(len(nums) % 2 == 0)
return (nums[i] + nums[j]) / 2
"""
For Example: input: nums1 = [1, 2] nums2 = [3, 4]
output: 2.0
"""
nums1 = [1, 2]
nums2 = [3, 4]
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('输出为:', result) # 2.5
方法二: 建立双指针,归并排序的思路
Tips:需要注意的是循环终止条件不需要遍历所有值,找到需要的即可。
时间复杂度是
O
(
m
+
n
2
)
=
O
(
m
+
n
)
O(\frac{m+n}{2})=O(m+n)
O(2m+n)=O(m+n),不满足本题要求,只提供思路。
执行用时 :68 ms, 在所有 Python3 提交中击败了26.49%的用户
内存消耗 :13.9 MB, 在所有 Python3 提交中击败了6.15%的用户
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
len1 = len(nums1)
len2 = len(nums2)
length = len1 + len2
p1 = 0
p2 = 0
r = []
while (len(r) < (length // 2 + 1)):
if (p1 == len1):
r.append(nums2[p2])
p2 = p2 + 1
elif (p2 == len2):
r.append(nums1[p1])
p1 = p1 + 1
else:
if (nums1[p1] < nums2[p2]):
r.append(nums1[p1])
p1 = p1 + 1
else:
r.append(nums2[p2])
p2 = p2 + 1
f = 1 if (length%2 == 0) else 0
if f == 0:
return r[length//2]
else:
return (r[length//2]+r[length//2-1])/2
"""
For Example: input: nums1 = [1, 2] nums2 = [3, 4]
output: 2.0
"""
nums1 = [1, 2]
nums2 = [3, 4]
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('输出为:', result) # 2.5
方法三: 二分查找的思路。时间复杂度 O ( l o g ( m + n ) ) O(log(m+n)) O(log(m+n)),满足题意。题注
执行用时 :52 ms, 在所有 Python3 提交中击败了78.70%的用户
内存消耗 :13.7 MB, 在所有 Python3 提交中击败了6.15%的用户
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
len1, len2 = len(nums1), len(nums2)
left, right, half_len = 0, len1, (len1 + len2 + 1) // 2
mid1 = (left + right) // 2
mid2 = half_len - mid1
while left < right:
if mid1 < len1 and nums2[mid2-1] > nums1[mid1]:
left = mid1 + 1
else:
right = mid1
mid1 = (left + right) // 2
mid2 = half_len - mid1
if mid1 == 0:
max_of_left = nums2[mid2-1]
elif mid2 == 0:
max_of_left = nums1[mid1-1]
else:
max_of_left = max(nums1[mid1-1], nums2[mid2-1])
if (len1 + len2) % 2 == 1:
return max_of_left
if mid1 == len1:
min_of_right = nums2[mid2]
elif mid2 == len2:
min_of_right = nums1[mid1]
else:
min_of_right = min(nums1[mid1], nums2[mid2])
return (max_of_left + min_of_right) / 2
"""
For Example: input: nums1 = [1, 2] nums2 = [3, 4]
output: 2.0
"""
nums1 = [1, 2]
nums2 = [3, 4]
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('输出为:', result) # 2.5
方法四: 寻找第k小的思路。时间复杂度 O ( l o g ( m + n ) ) O(log(m+n)) O(log(m+n)),满足题意。题注
执行用时 :52 ms, 在所有 Python3 提交中击败了78.70%的用户
内存消耗 :13.8 MB, 在所有 Python3 提交中击败了6.15%的用户
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
m, n = len(nums1), len(nums2)
total = m + n
if total & 1:
return self.findKth(nums1, m, nums2, n, total//2 + 1)
else:
return (self.findKth(nums1, m, nums2, n, total//2) + \
self.findKth(nums1, m, nums2, n, total//2 + 1))/2
def findKth(self, nums1, m, nums2, n, k):
if m > n:
return self.findKth(nums2, n, nums1, m, k)
if m == 0:
return nums2[k-1]
if k == 1:
return min(nums1[0], nums2[0])
p1 = min(k //2, m)
p2 = k - p1
if nums1[p1-1] < nums2[p2-1]:
return self.findKth(nums1[p1:], m - p1, nums2, n, k-p1)
elif nums1[p1-1] > nums2[p2-1]:
return self.findKth(nums1, m, nums2[p2:], n - p2, k-p2)
else:
return nums1[p1-1]
"""
For Example: input: nums1 = [1, 2] nums2 = [3, 4]
output: 2.0
"""
nums1 = [1, 2]
nums2 = [3, 4]
solution = Solution()
result = solution.findMedianSortedArrays(nums1, nums2)
print('输出为:', result) # 2.5
图解:
引用的图片展示的是方法三的部分思路,可以帮助分析,很不错,图片不显示可以去参考1自行查看。
参考
- https://github.com/MisterBooo/LeetCodeAnimation
- https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/dong-yong-er-fen-cha-zhao-mo-ban-lai-qiao-miao-jie/
- https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/di-k-xiao-shu-jie-fa-ni-zhen-de-dong-ma-by-geek-8m/
- https://www.bilibili.com/video/BV1d7411Q7GR