Leetcode 4 尋找兩個有序陣列的中位數

2021-10-03 03:32:56 字數 1971 閱讀 2542

給定兩個大小為 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

首先,觀察題目,題目要求時間複雜度為o(log (m+n)),要實現log級的複雜度的演算法一般會想到二分的思想,每次去掉接近一半的元素。

再回顧一下中位數的定義,如果某個有序陣列長度是奇數,中位數取排在最中間的數;如果是偶數,中位數取最中間的兩個數字的平均值。因此問題可以轉化為求兩個有序陣列中第k大的數的問題。題中涉及兩個有序陣列,假設兩個有序陣列的長度分別為m和n,由於兩個陣列長度之和 m+n 的奇偶不確定,因此需要分情況來討論。若(m+n)為奇數,直接找到最中間的數即可;若為偶數則需要求最中間兩個數的平均值。

為了簡化**,不分情況討論,使用乙個小trick,分別找排在第 (m+n+1) / 2 個和 (m+n+2) / 2 個的數字,然後求其平均值即可,這對奇偶數均適用。當(m+n)為奇數時, (m+n+1) / 2 與 (m+n+2) / 2 的值相等,兩者相加除以2仍然是其本身。

為了避免產生新的陣列從而增加時間複雜度,我們使用兩個變數i和j分別來標記陣列nums1和nums2的起始位置。

考慮一些邊界條件:

1)當某乙個陣列nums1的起始位置大於等於其陣列長度時,說明其所有數字均已經被淘汰了,相當於乙個空陣列,那麼實際上就變成了在另乙個陣列nums2中找第k大的數字,直接取nums2[j+k-1]即可。

2)當k=1時,取最小的數字即可,只需比較nums1和nums2的起始位置i和j上的數字即可。

下面重點來看如何實現找到第k個元素:

因為我們需要在兩個有序陣列中找到第k個元素,為了加快搜尋的速度,我們要使用二分法,對k二分,意思是我們需要分別在nums1和nums2中查詢第k/2個元素,注意這裡由於兩個陣列的長度不定,所以有可能某個陣列沒有第k/2個數字,所以我們需要先檢查一下,陣列中到底存不存在第k/2個數字,如果存在就取出來,否則就賦值乙個整型最大值int_max。如果某個陣列沒有第k/2個數字,那麼我們就淘汰另乙個數字的前k/2個數字即可。有沒有可能兩個陣列都不存在第k/2個數字呢,這道題裡是不可能的,因為我們的k不是任意給的,而是給的m+n的中間值,所以必定至少會有乙個陣列是存在第k/2個數字的。最後就是二分法的核心啦,比較這兩個陣列的第k/2小的數字midval1和midval2的大小,如果第乙個陣列的第k/2個數字小的話,那麼說明我們要找的數字肯定不在nums1中的前k/2個數字,所以我們可以將其淘汰,將nums1的起始位置向後移動k/2個,並且此時的k也自減去k/2,呼叫遞迴。反之,我們淘汰nums2中的前k/2個數字,並將nums2的起始位置向後移動k/2個,並且此時的k也自減去k/2,呼叫遞迴即可。

class

solution

intfindkth

(vector<

int>

& nums1,

int i, vector<

int>

& nums2,

int j,

int k)

int mid1 =

((i + k /2-

1)< nums1.

size()

)? nums1[i + k /2-

1]: int_max;

int mid2 =

((j + k /2-

1)< nums2.

size()

)? nums2[j + k /2-

1]: int_max;

if(mid1 < mid2)

else}}

;

LeetCode 4 尋找兩個有序陣列的中位數

給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0 示例 2 nums1 1,2 ...

LeetCode 4 尋找兩個有序陣列的中位數

給定兩個大小為 m 和 n 的有序陣列nums1和nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設nums1和nums2不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0示例 2 nums1 1,2 nums2 3,...

LeetCode4 尋找兩個有序陣列的中位數

給定兩個大小為 m 和 n 的有序陣列nums1和nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設nums1和nums2不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0示例 2 nums1 1,2 nums2 3,...