力扣 尋找兩個正序陣列的中位數

2021-10-08 02:07:28 字數 1998 閱讀 3098

給定兩個大小為 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,通常都需要用到二分查詢,這道題也是通過二分查詢實現

根據中位數的定義,當m+n是奇數的時候,中位數是兩個有序陣列中的第(m+n)/2個元素,當m+n是偶數的時候,中位數是兩個有序陣列中的第(m+n)/2和第(m+n)/2+1個元素的平均值。因此,這道題可以轉換為尋找兩個有序陣列中的第k小的數,其中k為(m+n)/2或者(m+n)/2+1

假設有序陣列分別是a和b要找到第k個元素,我們可以比較a[k/2-1]和b[k/2-1],其中/標識除法符號。由於a[k/2-1]和b[k/2-1]的前面分別有a[0 … k/2-2]和b[0 … k/2-2],即k/2-1個元素,對於a[k/2-1]和b[k/2-1]中的較小值,最多只有(k/2-1)+(k/2-1) <=k-2個元素比他小,那麼他就不是第k個小的數

因此我們可以歸納出三種情況

可以看到,比較a[k/2-1]和b[k/2-1]之後可以排除k/2個可能是第k小的數,查詢範圍小了一半.同時,我們將在排除後的新陣列上繼續進行二分查詢,並且根據我們排除的個數,減小k的值,這是因為我們排除的數都是不大於第k小的數字

有以下三種情況需要特殊處理

package 題庫.尋找兩個正序陣列中位數;

public

class

solution

;int

num2=

; solution solution =

newsolution()

; system.out.

println

(solution.

findmediansortedarrays

(num1,num2));

}/**

* 在兩個正向陣列中獲得中位數

* @param num1

* @param num2

* @return

*/private

double

findmediansortedarrays

(int

num1,

int[

] num2)

else

}/**

* 二分查詢法

* @param a

* @param b

* @param k 需要查詢的第k個元素

* @return

*/public

double

binarysearch

(int

a,int[

]b,int k)

//b陣列索引等於b陣列的長度

if(bi == bl)

//第k個字元是不是第乙個

if(k ==1)

//常規操作,獲取第k/2個元素的索引或者如果超出界限獲取該陣列最後乙個元素

nai = math.

min(ai+k/

2, al)-1

; nbi = math.

min(bi+k/

2, bl)-1

;//兩種常規情況

//該索引a陣列大於b陣列

if(a[nai]

>= b[nbi]

)else}}

}

力扣演算法篇 尋找兩個正序陣列的中位數

尋找兩個正序陣列的中位數 給定兩個大小分別為m和n的正序 從小到大 陣列nums1和nums2。請你找出並返回這兩個正序陣列的中位數。例項 題解 遍歷兩個陣列 得到有序的合併陣列並找到中位數 class solution vector int combine int i 0 int j 0 whil...

力扣第4題 尋找兩個正序陣列的中位數

給定兩個大小為 m 和 n 的正序 從小到大 陣列 nums1 和 nums2。請你找出並返回這兩個正序陣列的中位數。高階 你能設計乙個時間複雜度為 o log m n 的演算法解決此問題嗎?示例 1 輸入 nums1 1,3 nums2 2 輸出 2.00000 解釋 合併陣列 1,2,3 中位數...

尋找兩個正序陣列的中位數

尋找兩個正序陣列的中位數 二分法根據中位數的定義,當 m n 是奇數時,中位數是兩個有序陣列中的第 m n 2 個元素,當 m n 是偶數時,中位數是兩個有序陣列中的第 m n 2 個元素和第 m n 2 1 個元素的平均值。因此,這道題可以轉化成尋找兩個有序陣列中的第 k 小的數,其中 k 為 m...