思路:
暴力解決:合併陣列並排序,簡單且一定能實現,時間複雜度o(m+n)
由於兩個陣列已經排好序,可一邊排序一邊合併,用時為第一種的一半,時間複雜度依然為o(m+n)
由題目,只需要找中位數,即中位數兩側的元素並不需要完全排序,且兩陣列長度已知且有序,合併後中位數的索引是固定的,所以只要找到這乙個或計算中位數的兩個數的索引即可,既然為查詢,可用二分查詢,即可實現時間複雜度為o(log(m+n))
解決方案:
def findmediansortedarrays(nums1, nums2):
def mid_index(left, right):
return (left + right) // 2
# 以下稱第乙個陣列為a,第二個陣列為b
def findmediansortedarrayssorted(short_nums, m, long_nums, n):
is_odd = (m + n) % 2
mid = (m + n - 1) // 2
if m == 0:
if is_odd:
return long_nums[mid]
else:
return float(long_nums[mid] + long_nums[mid + 1]) / 2
left = 0
right = m - 1
i = mid_index(left, right)
while left <= i <= right:
j = mid - (i + 1)
# 若a陣列左側最大元素大於b陣列右側最小元素,中位索引左移
if i > 0 and short_nums[i] > long_nums[j + 1]:
right = i
i = mid_index(left, right)
# 若b陣列左側最大元素大於b陣列右側最小元素,中位索引右移
elif i < m - 1 and long_nums[j] > short_nums[i + 1]:
left = i + 1
i = mid_index(left, right)
# 從0索引開始查詢,查詢並未結束
# 其實只有陣列長度為2時才會出現這種情況
elif i == 0 and m > 1 and long_nums[j] > short_nums[i + 1]:
left = i + 1
i = mid_index(left, right)
# 達成結束條件
else:
if i == 0:
# 該陣列最小值比在另乙個陣列中可能的中位值大
# 即整個陣列所有元素都應該放在右側
if short_nums[i] > long_nums[j + 1]:
max_left = long_nums[j + 1]
if j + 3 <= n:
min_right = min(short_nums[i], long_nums[j + 2])
else:
min_right = short_nums[i]
else:
# 只出現在兩個只有乙個元素,且a陣列元素小於b陣列元素的情況下
# 應該可以合併到其他情況中,但是腦子不夠用了,希望有人可以提意見
if j == -1:
max_left = short_nums[i]
min_right = long_nums[j + 1]
else:
max_left = max(short_nums[i], long_nums[j])
if m > 1:
min_right = min(short_nums[i + 1], long_nums[j + 1])
else:
min_right = long_nums[j + 1]
# 檢索到了最後乙個元素
elif i == m - 1:
# 大坑,兩陣列等長時,檢索到末端時j的值為-1
# python列表的-1索引可以取到最後乙個元素,debug才找到問題
if j == -1:
max_left = short_nums[i]
min_right = long_nums[j + 1]
# a陣列最大值小於b陣列中位數
elif short_nums[i] < long_nums[j]:
max_left = long_nums[j]
min_right = long_nums[j + 1]
else:
max_left = max(short_nums[i], long_nums[j])
min_right = long_nums[j + 1]
# 在中間位置找到正確的中位數
else:
max_left = max(short_nums[i], long_nums[j])
min_right = min(short_nums[i + 1], long_nums[j + 1])
if is_odd:
return max_left
else:
return float(max_left + min_right) / 2
a = len(nums1)
b = len(nums2)
if a > b:
return findmediansortedarrayssorted(nums2, b, nums1, a)
else:
return findmediansortedarrayssorted(nums1, a, nums2, b)
leetcode演算法練習 88 合併兩個有序陣列
所有題目源 git位址 題目給你兩個有序整數陣列 nums1 和 nums2,請你將 nums2 合併到 nums1 中,使 nums1 成為乙個有序陣列。說明 初始化 nums1 和 nums2 的元素數量分別為 m 和 n 你可以假設 nums1 有足夠的空間 空間大小大於或等於 m n 來儲存...
leetcode刷題 021合併兩個有序鍊錶
將兩個有序鍊錶合併為乙個新的有序鍊錶並返回。新煉表是通過拼接給定的兩個鍊錶的所有節點組成的。示例 輸入 1 2 4,1 3 4 輸出 1 1 2 3 4 4 definition for singly linked list.class listnode def init self,x self.v...
LeetCode 題 88 合併兩個有序陣列
給定兩個有序整數陣列 nums1 和 nums2,將 nums2 合併到 nums1 中,使得 num1 成為乙個有序陣列。說明 初始化 nums1 和 nums2 的元素數量分別為 m 和 n。你可以假設 nums1 有足夠的空間 空間大小大於或等於 m n 來儲存 nums2 中的元素。示例 輸...