給定兩個大小為 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
思考:
看了grandyang的部落格,慢慢想明白才寫的!真的是很細心耐心的博主!
限制了時間複雜度為
o(log (m+n)),想到了應該使用二分查詢法來求解。
尋找陣列的中位數的小技巧:假設陣列的長度是m,找第(m+1)/2位和第(m+2)/2位的元素,兩者的平均數即為陣列的中位數。
我們可以
在兩個陣列之間使用二分查詢。分別去查詢每個陣列的(m+n+1)/2的元素和(m+n+2)/2的元素求平均數。
首先:定義乙個函式來在兩個有序陣列中找到第k個元素(這道題可以出成:兩個有序陣列找第n大)
有兩個邊緣情況要注意:
1、當陣列的起始位置已經大於等於陣列的長度(這時只用去尋找另乙個陣列即可),此時表明這個陣列中所有元素已經被排除了,所以直接去尋找另乙個陣列起始位置:j + k /2 -1的元素。
2、當k == 1時,表示要查詢當前陣列的首元素,舉個例子如下圖:
演算法思路:
分別在nums1
和nums2
中查詢第k/2個元素,陣列長度是不定的,所以要確定當前的陣列有沒有k/2個元素,
如果存在就取作midval值,否則就賦值上乙個整型最大值int_max。
如果某個陣列沒有第k/2個數字,那麼我們就淘汰另乙個陣列的前k/2個數字即可。若找到的midval1 大於 midval2,說明該去查詢num1的下半區間[i +k/2 -1 +1,end] (i+k/2 -1 :mid 另外一半區間應該是起始mid +1 ),有序陣列的中位數,左邊的都比它小,右邊的都比它大。
重點理解:「如果某個陣列沒有第k/2個數字,那麼我們就淘汰另乙個陣列的前k/2個數字即可。」
一開始沒理解後來主動問了博主:grandyang。舉例子:假設nums1 =,nums2=,k=4,我們要在兩個陣列中找第四個的元素,分別在nums1和nums2中找第2個的元素,現在nums1只有乙個數字,所以不存在第二大的數字,而nums2前兩個數字可以直接跳過。
因為要求整個兩個陣列中第4個的元素,如果num1中數字大於num2第k/2位,那麼合併之後也是在num2第k/2位之後,而num2的前k/2位是沒用的,直接跳過;如果num1中數字是小於num2第k/2位置,但是元素個數是小於k/2,即使合併,這兩部分元素個數也只小於k個,所以也不可能在num2的k/2部分,所以第4個的元素肯定不會出現在乙個排序陣列nums2的前兩位,所以可以直接跳過。
/*查詢兩個陣列中排列第k個數*/
int findkthnumber(vector& nums1,int i ,vector& nums2,int j,int k)
整體**:
/*分清 起始位置 和 第幾個元素 */
int findkthnumber(vector& nums1,int i ,vector& nums2,int j,int k)
class solution
};
4 尋找兩個有序陣列的中位數
給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。示例 1 nums1 1,3 nums2 2 則中位數是 2.0 示例 2 nums1 1,2 ...
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...
4 尋找兩個有序陣列的中位數
給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 o log m n 你可以假設 nums1 和 nums2 不會同時為空。class solution def findmediansortedarrays self,n...