LeetCode 4. 兩個排序陣列的中位數
題目描述:
解題思路
1. 歸併法
首先想到的思路就是歸併排序中的歸併操作,將兩個有序的陣列進行重組之後O(1)的查詢到中位數元素,但是歸併的時間複雜度為O(n+m),與要求的O(log(m+ n))相差很多,因此不可行。
2. 分治法
因為時間複雜度要求為O(log(m+n))因此採用的是分治演算法這樣能保證時間複雜度是log級別。
但是如何進行分治是這道題的難點。
首先需要轉化一下思路,求中位數的含義既是:1. 當n為奇數時求(n/2+1)大的數;2. 當n為偶數時求(n/2)大與(n/2+1)大的數。因此這個問題可以轉化為求第k大的數的問題。
在兩個有序陣列中如何求第K大的數?
假設第一個陣列中前p項,第二個陣列中前q項滿足p+q = k-1,那麼第k大的數一定是p+1或者q+1位置上的數。
講到這裡就可以通過分治來將問題的規模縮小了。
我們令p=k/2, q = k-p;
1) 如果第一個陣列中第p個數 < 第二個陣列中第q個數,說明第一個陣列中前p個數一定小於第k大數,但是無法確定q位置代表的數字是否比第k個元素大,因此需要繼續尋找。此時可以將第一個陣列的元素減少p個,k -= p,來縮小範圍。
2) 如果第一個陣列中第p個數 > 第二個陣列中第q個數,同理說明第二個陣列中前1個數一定小於第k大數,但是無法確定p位置代表的數字是否比第k個元素大,因此需要繼續尋找。此時可以將第二個陣列的元素減少q個,k -= q,來縮小範圍。
3) 如果第一個陣列中第p個數 = 第二個陣列中第q個數,說明第K個元素為p或者q位置上的數字,因為他們之前的數字已經到達了k-1。
注意:
- k == 1時,說明需要找的數在當前剩下的兩個陣列的第一個元素中去一個小的;
- 當有一個陣列的長度為0了,說明只能在另一個陣列中取數,因此返回第k大元素即可;
- 為了保證判斷陣列是否為空,始終讓第一個陣列作為長度較短的陣列;
程式碼實現:
class Solution
{
public:
double FindK(vector<int>& nums1, vector<int>& nums2,int start1, int start2, int len1, int len2, int k)
{
if(len1 > len2)
return FindK(nums2, nums1, start2, start1, len2, len1, k);
if(len1 == 0)
return nums2[start2+k-1]*1.0;
if(k == 1)
return min(nums1[start1], nums2[start2])*1.0;
int p = min(k/2, len1);
int q = k-p;
if(nums1[start1+p-1] < nums2[start2+q-1])
return FindK(nums1, nums2, start1+p, start2, len1-p, len2, k-p);
if(nums1[start1+p-1] > nums2[start2+q-1])
return FindK(nums1, nums2, start1, start2+q, len1, len2-q, k-q);
return nums1[start1+p-1];
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
{
int n = nums1.size();
int m = nums2.size();
double Median = 0.0;
int k = ((m+n)>>1) + 1;
if(m == 1 && n == 1)
{
return (nums1[0]+nums2[0])*1.0/2;
}
if((n+m)&1)
{
Median = FindK(nums1, nums2, 0, 0, n, m, k);
}
else
{
//cout<<FindK(nums1, nums2, 0, 0, n, m, k-1)<<endl;
Median = (FindK(nums1, nums2, 0, 0, n, m, k-1)+ FindK(nums1, nums2, 0, 0, n, m, k))/2.0;
}
return Median;
}
};
相關文章
- 4. 兩個排序陣列的中位數排序陣列
- LeetCode-兩個排序陣列的中位數LeetCode排序陣列
- LeetCode-4. 兩個排序陣列的中位數LeetCode排序陣列
- 4. 尋找兩個正序陣列的中位數陣列
- [LeetCode 刷題] 4. 尋找兩個有序陣列的中位數 (Hard)LeetCode陣列
- 演算法-兩個排序陣列的中位數演算法排序陣列
- LeetCode解題(C++)-4. 尋找兩個有序陣列的中位數LeetCodeC++陣列
- 【LeetCode Hot 100】4. 尋找兩個正序陣列的中位數LeetCode陣列
- 兩個有序陣列的中位數陣列
- 從0打卡leetcode之day 5 ---兩個排序陣列的中位數LeetCode排序陣列
- leetcode 4. Median of Two Sorted Arrays 尋找兩個正序陣列的中位數(困難)LeetCode陣列
- LeetCode--尋找兩個有序陣列的中位數(05)LeetCode陣列
- 尋找兩個有序陣列的中位數陣列
- LeetCode第4題:尋找兩個有序陣列的中位數LeetCode陣列
- [LeetCode] Median of Two Sorted Arrays 兩個有序陣列的中位數LeetCode陣列
- 尋找兩個正序陣列中的中位數陣列
- [Python手撕]兩個升序陣列的中位數Python陣列
- 每天一道演算法題:求兩個排序陣列的中位數演算法排序陣列
- GO實現:leetcode之尋找兩個正序陣列的中位數GoLeetCode陣列
- 【遞迴打卡1】在兩個長度相等的排序陣列中找到上中位數遞迴排序陣列
- 尋找兩個正序陣列的中位數問題,方法一:合併陣列檢索法陣列
- 力扣演算法題:尋找兩個正序陣列的中位數力扣演算法陣列
- leetcode 349. 兩個陣列的交集LeetCode陣列
- LeetCode-349-兩個陣列的交集LeetCode陣列
- Leetcode[陣列] 26. 刪除排序陣列中的重複項LeetCode陣列排序
- 二位陣列排序陣列排序
- 4.陣列陣列
- PHP陣列多個欄位分別排序PHP陣列排序
- 找到兩個陣列中的公共元素陣列
- 在陣列中尋找和為指定值的兩個數陣列
- 二維陣列根據某個欄位排序陣列排序
- python實現給定一個數和陣列,求陣列中兩數之和為給定的數Python陣列
- LeetCode題集-4 - 尋找兩個有序陣列的中位數,圖文並茂,六種解法,萬字講解LeetCode陣列
- LeetCode-350-兩個陣列的交集 IILeetCode陣列
- 【LeetCode】Sort Colors 陣列排序LeetCode陣列排序
- 刪除排序陣列中的重複數字排序陣列
- 【LeetCode】88. 合併兩個有序陣列LeetCode陣列
- 給定陣列中找到最大的兩個數陣列