Leetcode演算法題 兩個有序陣列求中位數

2021-09-25 09:54:10 字數 2843 閱讀 9356

思路:

暴力解決:合併陣列並排序,簡單且一定能實現,時間複雜度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 中的元素。示例 輸...