[LeetCode解題攻略] 4. Median of Two Sorted Arrays

更新 發佈閱讀 8 分鐘

題目描述

給定兩個已排序的陣列 nums1nums2,請找到並返回這兩個陣列的中位數。要求時間複雜度為 O(log(min(m, n))),其中 mn 分別是兩個陣列的長度。

範例:

  • 輸入:nums1 = [1, 3], nums2 = [2]
    輸出:2.0
  • 輸入:nums1 = [1, 2], nums2 = [3, 4]
    輸出:2.5

解題思路

中位數問題在兩個已排序陣列中可以透過二分搜尋來解決。為了達成 O(log(min(m, n))) 的時間複雜度要求,我們可以在較短的陣列中進行二分搜尋,從而縮小運算範圍。

思路概述:

  1. 分割陣列:將兩個陣列視為一整體,分割成兩部分,使得左邊部分的數量等於右邊部分。
  2. 選擇左側最大值右側最小值:中位數即是左側最大值和右側最小值的平均數或其中一個。
  3. 二分搜尋優化:在較短的陣列中進行分割調整,直至找到合適的分割點,使得左側的數字都小於右側。

解法一:二分搜尋

在這裡,我們以較短的陣列進行二分搜尋。透過在 nums1 中調整分割點,可以計算出 nums2 中相應的分割位置,並驗證是否滿足條件。最終的分割結果即為中位數。

步驟詳解:

  1. 確保 nums1 是較短的陣列(如果不是,交換 nums1nums2)。
  2. 設置 lowhighnums1 的左右邊界。
  3. nums1 中進行二分搜尋,計算分割點 partition1partition2
  4. 確認條件:
    • nums1[partition1 - 1] <= nums2[partition2]nums2[partition2 - 1] <= nums1[partition1],則找到合適的分割點。
  5. 計算中位數:
    • 若兩陣列總長度為奇數,則中位數為左側最大值。
    • 若總長度為偶數,中位數為左側最大值與右側最小值的平均。

程式碼實現:

class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
# 確保 nums1 是較短的陣列
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1

m, n = len(nums1), len(nums2)
low, high = 0, m

while low <= high:
partition1 = (low + high) // 2
partition2 = (m + n + 1) // 2 - partition1

# 邊界情况
max_left1 = float('-inf') if partition1 == 0 else nums1[partition1 - 1]
min_right1 = float('inf') if partition1 == m else nums1[partition1]
max_left2 = float('-inf') if partition2 == 0 else nums2[partition2 - 1]
min_right2 = float('inf') if partition2 == n else nums2[partition2]

if max_left1 <= min_right2 and max_left2 <= min_right1:
if (m + n) % 2 == 0:
return (max(max_left1, max_left2) + min(min_right1, min_right2)) / 2
else:
return max(max_left1, max_left2)
elif max_left1 > min_right2:
high = partition1 - 1
else:
low = partition1 + 1
  • 時間複雜度O(log(min(m, n))),因為我們在較短的陣列中進行二分搜尋。
  • 空間複雜度O(1),僅使用常數空間來存儲指標和變量。

解法二:合併排序法

另一種解法是合併兩個排序陣列,但這種解法的時間複雜度為 O(m + n),不符合題目要求的 O(log(min(m, n)))。儘管如此,若不考慮時間限制,這種方法對理解中位數概念有幫助。

步驟詳解:

  1. 將兩個陣列合併。
  2. 將合併過後的陣列排序。
  3. 如果合併過後長度為奇數,返回中間值;若為偶數,返回兩個中間值的平均數。

程式碼實現:

class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
list_combined = []

# 合併兩個陣列
list_combined = nums1 + nums2

# 排序陣列
list_combined.sort()

# 計算中位數
if len(list_combined) % 2 == 0:
return (list_combined[int(len(list_combined) * 0.5) - 1] + list_combined[int(len(list_combined) * 0.5)]) / 2.0
else:
return list_combined[floor(len(list_combined) * 0.5)]
  • 時間複雜度O(m + n),因為需要遍歷兩個陣列並將所有元素合併到一個新陣列中。
  • 空間複雜度O(m + n),因為使用了額外的空間來儲存合併的陣列。

小結

這道題主要測試二分搜尋在數組合併與排序中的應用。解法一通過較短陣列的二分搜尋,巧妙地達到 O(log(min(m, n))) 的時間複雜度,是處理中位數問題的最優解法。


留言
avatar-img
追極光的北極熊|軟體工程師的小天地
16會員
170內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/03/28
給定一個 m x n 的矩陣 matrix,請按照 螺旋順序(spiral order) 返回矩陣中的所有元素。
2025/03/28
給定一個 m x n 的矩陣 matrix,請按照 螺旋順序(spiral order) 返回矩陣中的所有元素。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
看更多
你可能也想看
Thumbnail
題目會給定一個存有整數的陣列,要求我們依照下列規則進行排序,由小排到大,升序排列。
Thumbnail
題目會給定一個存有整數的陣列,要求我們依照下列規則進行排序,由小排到大,升序排列。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
題目:建立一個函數,該函數返回給定最小 4 個正整數的數組的兩個最低正數的總和。不會傳入浮點數或非正整數。例如,當一個數組像 [19, 5, 42, 2, 77], 輸出應該是 7。 [10, 343445353, 3453445, 3453545353453] 應該回來 3453
Thumbnail
題目:建立一個函數,該函數返回給定最小 4 個正整數的數組的兩個最低正數的總和。不會傳入浮點數或非正整數。例如,當一個數組像 [19, 5, 42, 2, 77], 輸出應該是 7。 [10, 343445353, 3453445, 3453545353453] 應該回來 3453
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
題目會給我們兩條已經從小到大排序好的串列,要求我們依照從小到大的順序,合併這兩條串列。
Thumbnail
題目會給我們兩條已經從小到大排序好的串列,要求我們依照從小到大的順序,合併這兩條串列。
Thumbnail
題目敘述 題目會給我們一個陣列,要求我們返回 兩數之和=target所在的陣列索引值。 題目還額外保證,一定剛好有一組解。 測試範例 Example 1: Input: nums = [2,7,11,15], target = 9 Output: [0,1]
Thumbnail
題目敘述 題目會給我們一個陣列,要求我們返回 兩數之和=target所在的陣列索引值。 題目還額外保證,一定剛好有一組解。 測試範例 Example 1: Input: nums = [2,7,11,15], target = 9 Output: [0,1]
Thumbnail
題目會給們一個陣列,還有一個k值。 好陣列定義是: 有包含nums[k]的子陣列。 分數定義是: min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1) 其中, i, j 分別是子陣列的左端點和右端點 請問,好的子陣列的最大分數是多少?
Thumbnail
題目會給們一個陣列,還有一個k值。 好陣列定義是: 有包含nums[k]的子陣列。 分數定義是: min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1) 其中, i, j 分別是子陣列的左端點和右端點 請問,好的子陣列的最大分數是多少?
Thumbnail
三種做法所花的時間都不同,請試著一步步優化,在只跑一次迴圈下完成吧!
Thumbnail
三種做法所花的時間都不同,請試著一步步優化,在只跑一次迴圈下完成吧!
Thumbnail
題目會給定一個陣列,要求我們把裡面的數字依照奇偶數去排序, 偶數的排在前面,奇數的排在後面。
Thumbnail
題目會給定一個陣列,要求我們把裡面的數字依照奇偶數去排序, 偶數的排在前面,奇數的排在後面。
Thumbnail
題目會給定我們一個陣列,陣列長度為n。 要求我們找出裡面出現次數超過 n / 3次的數字。
Thumbnail
題目會給定我們一個陣列,陣列長度為n。 要求我們找出裡面出現次數超過 n / 3次的數字。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News