參考:
給定兩個大小為 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
遇到本題應該先考慮中位數的意義是什麼
中位數把陣列分為了兩部分左邊的部分肯定大於右邊的部分
並且看到要求的時間複雜度帶log,那麼肯定用到了折半查詢
我們把兩個陣列分為四部分,陣列自己的左邊部分肯定小於右邊部分
但是還需要保證陣列a的左邊部分最大值要小於陣列b的右邊部分最小值
陣列b的左邊部分最大值要小於陣列a的右邊部分最小值
滿足了上述的條件就完成了兩個陣列的分割
若陣列a的分割點在i陣列b的分割點在j,m和n為陣列ab的長度
i+j = m-i+n-j;
i+j = m-i+n-j+1;//加一是因為如果兩個陣列總數為奇數那麼左半部分就比右半部分多乙個數字
綜上得j=(m+n+1)/2-i;// 因為+1之後/2有因為轉為int之後會遮蔽0.5所以這個+1並沒有影響但是卻可以統合奇偶不同的問題
得到了分割點i與j之間的關係此時只要找打了其中乙個分割點那麼另乙個分割點也就自然出來了
我們找i的分割點
使用折半查詢(其實題目中看出要用折半查詢,但是不是用折半查詢直接找中間值而是用折半查詢尋找分割點,但是找到了分割點其實也就可以找到中間值
找到分割點後要根據不同的分割情況和陣列長度的奇偶情況進行處理
如果陣列總長度是奇數那麼返回左側的最大值就是中位數
如果陣列總長度是偶數那麼(左側最大值+右側最小值)/2就是中位數
此時就需要找左側最大值與右側最小值
找左側最大值時陣列分割有三種情況
分割點在陣列a或陣列b的最前面
此時左側就只有乙個陣列的一半將這一半的最大值賦給左側最大值即可
否則就需要找兩個陣列左側的最大值,然後取他們之間的最大值
此時找到左側最大值如果是奇數總長度返回即可
如果是偶數長度繼續尋找右側最小值
找右側最小值也分為不同的情況
如果分割點在陣列a或b的最後面
此時右側只有某個陣列的一半
此時在這一半中找最小值賦值給右側最小值即可
否則就需要找兩個陣列的的右側部分的最小值,在找到的兩個最小值中取最小值賦值給右側最小值
詳情見參考
package priv.wzb.leet_code.median_of_two_sorted_arrays;
/** * @author satsuki
* @time 2019/7/19 14:55
* @description:
* 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。
* * 請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o(log(m + n))。
* * 你可以假設 nums1 和 nums2 不會同時為空。
* */
public
class
solution3
// 定義分割線的左側與右側
// 其實imin和imax代表的是在折半查詢用到的陣列的最左側和最右側
int imin =
0,imax = m;
// 隨著折半查詢的繼續在不停的改動,一般查詢到了正確的分割點也就是i在正確的位置就可以繼續執行
while
(imin<=imax)
else
if(j!=
0&&i!=m&&nums2[j-1]
>nums1[i]
)else
else
if(j ==0)
else
// 陣列總長度為奇數
// 直接返回左側最大值即可if(
(m+n)%2
==1)// 陣列長度是偶數
// 找右側最小值
int minright =0;
// 分三種情況
// 分割線在陣列的最後面
if(i==m)
else
if(j==n)
else
return
(maxleft+minright)
/2.0;}
}return
0.0;
}public
static
void
main
(string[
] args)
;// int nums2 = new int;
// int nums1= new int;
// int nums2 = new int;
// int nums1= new int;
// int nums2 = new int;
// int nums1= new int;
// int nums2 = new int;
// int nums2= new int;
// int nums1 = new int;
// int nums1= new int;
// int nums2 = new int;
// int nums1= new int{};
// int nums2 = new int;
// int nums1= new int;
// int nums2 = new int;
int[
] nums1=
newint
;int
nums2 =
newint
; system.out.
println
(new
solution3()
.findmediansortedarrays
(nums1,nums2));
}}
尋找兩個有序陣列的中位數
尋找兩個有序陣列的中位數 user hihone date 2019 1 31 time 16 32 description 給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 ...
尋找兩個有序陣列的中位數
思路 將兩個陣列排序,然後判斷陣列長度,長度為單數,則取二分之一處的數,否則取二分之一處和二分之一減一處的數之和除以2.var findmediansortedarrays function nums1,nums2 var mid math.floor arr.length 2 if arr.len...
尋找兩個有序陣列的中位數
給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0示例 2 nums1 1,2 n...