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: 這種方法時間複雜度取決於排序方法,可以參考我的一些筆記 快速排序。
本題的話時間複雜度不滿足要求,只提供思路,另外,之所以編譯通過,是因爲驗證集合維度過小。
另外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:需要注意的是循環終止條件不需要遍歷所有值,找到需要的即可。
時間複雜度是,不滿足本題要求,只提供思路。
執行用時 :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
方法三: 二分查找的思路。時間複雜度,滿足題意。題注
執行用時 :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小的思路。時間複雜度,滿足題意。題注
執行用時 :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