[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))) 的時間複雜度,是處理中位數問題的最優解法。


歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
留言0
查看全部
發表第一個留言支持創作者!
給定一個字串 s,請找出其中不含重複字母的最長子字串的長度。
在這篇文章中,我們將深入探討 LeetCode 題目「2. Add Two Numbers」的解法。這道題目考察對鏈結串列 (Linked List) 操作和進位處理的掌握。
在 LeetCode 上,Two Sum 這道題目主要考察如何高效地處理數組和數據查找問題,是面試中常見的問題之一。今天我們將詳細解說這道題目,並提供幾種解題方法。
給定一個字串 s,請找出其中不含重複字母的最長子字串的長度。
在這篇文章中,我們將深入探討 LeetCode 題目「2. Add Two Numbers」的解法。這道題目考察對鏈結串列 (Linked List) 操作和進位處理的掌握。
在 LeetCode 上,Two Sum 這道題目主要考察如何高效地處理數組和數據查找問題,是面試中常見的問題之一。今天我們將詳細解說這道題目,並提供幾種解題方法。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
題目敘述 Find K-th Smallest Pair Distance 給定一個輸入陣列nums和 參數k。 請找出第k小的pair distance是多少? pair distance定義為 abs( nums[i] - nums[j]), i 不等於j 也就是任意兩陣列元素差值的絕對值
Thumbnail
題目敘述 Combination Sum II_Leetcode #40 給定一個整數陣列candidates 和 目標值target。 每個陣列元素只能選擇一次,請問有多少種組合方法,可以使得組合數總和 = target? 請把滿足組合數總和 = target的組合方法以陣列的形式返回答案
Thumbnail
題目敘述 Make Two Arrays Equal by Reversing Subarrays 題目給定兩個輸入陣列,請問能否透過子陣列的反轉讓兩個陣列相等? 子陣列的反轉操作次數不受限制。 如果可以,返回True 如果不行,返回False
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
給定兩個輸入陣列,第一個陣列代表每個人的姓名,第二個陣列代表每個人的身高。依照身高從高到矮進行排列,輸出每個人的名字。本文介紹了一個根據身高排列人名的算法,並提供了相關的程式碼和時間複雜度分析。
Thumbnail
題目敘述 Intersection of Two Arrays II 給定兩個輸入陣列,請找出兩個陣列交集的元素,並且依照出現次數輸出。 測試範例 Example 1: Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2,2] 交集元素
Thumbnail
題目敘述 Longest Arithmetic Subsequence of Given Difference 給定一個整數陣列nums,請找出給定公差difference的最長的等差數列的長度是多少?
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,和一個指定的k值。 請問,在輸入陣列nums中,有幾個子陣列的元素總合恰好為k ? 例如: nums = [1,2,3], k = 3 則有兩個子陣列的元素總合為3,分別是[1,2] 和 [3] 如果是第一次聽到或接觸前綴和prefix的同學
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
題目敘述 Find K-th Smallest Pair Distance 給定一個輸入陣列nums和 參數k。 請找出第k小的pair distance是多少? pair distance定義為 abs( nums[i] - nums[j]), i 不等於j 也就是任意兩陣列元素差值的絕對值
Thumbnail
題目敘述 Combination Sum II_Leetcode #40 給定一個整數陣列candidates 和 目標值target。 每個陣列元素只能選擇一次,請問有多少種組合方法,可以使得組合數總和 = target? 請把滿足組合數總和 = target的組合方法以陣列的形式返回答案
Thumbnail
題目敘述 Make Two Arrays Equal by Reversing Subarrays 題目給定兩個輸入陣列,請問能否透過子陣列的反轉讓兩個陣列相等? 子陣列的反轉操作次數不受限制。 如果可以,返回True 如果不行,返回False
Thumbnail
題目敘述 Sort Array by Increasing Frequency Leetcode #1636 給定一個輸入陣列,請依照出現頻率的多寡從低頻到高頻排列陣列元素。 如果有兩個元素的出現頻率相同,依照元素大小從大到小排列。 測試範例 Example 1: Input: nums
Thumbnail
給定兩個輸入陣列,第一個陣列代表每個人的姓名,第二個陣列代表每個人的身高。依照身高從高到矮進行排列,輸出每個人的名字。本文介紹了一個根據身高排列人名的算法,並提供了相關的程式碼和時間複雜度分析。
Thumbnail
題目敘述 Intersection of Two Arrays II 給定兩個輸入陣列,請找出兩個陣列交集的元素,並且依照出現次數輸出。 測試範例 Example 1: Input: nums1 = [1,2,2,1], nums2 = [2,2] Output: [2,2] 交集元素
Thumbnail
題目敘述 Longest Arithmetic Subsequence of Given Difference 給定一個整數陣列nums,請找出給定公差difference的最長的等差數列的長度是多少?
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,和一個指定的k值。 請問,在輸入陣列nums中,有幾個子陣列的元素總合恰好為k ? 例如: nums = [1,2,3], k = 3 則有兩個子陣列的元素總合為3,分別是[1,2] 和 [3] 如果是第一次聽到或接觸前綴和prefix的同學