leetcode 4. 寻找两个有序数组的中位数,c语言
leetcode上第四道題,如下。
給定兩個(gè)大小為 m 和 n 的有序數(shù)組?nums1 和?nums2。請(qǐng)你找出這兩個(gè)有序數(shù)組的中位數(shù),并且要求算法的時(shí)間復(fù)雜度為?O(log(m + n))。你可以假設(shè)?nums1?和?nums2?不會(huì)同時(shí)為空。?題目很簡(jiǎn)潔,首先要搞懂中位數(shù)的概念,這玩意和平均數(shù)是有差別的。一開(kāi)始我就搞錯(cuò)了,把中位數(shù)和平均數(shù)搞混了,結(jié)果做了半天結(jié)果越來(lái)越離譜。百度的中位數(shù)概念如下:
中位數(shù)是按順序排列的一組數(shù)據(jù)中居于中間位置的數(shù),即在這組數(shù)據(jù)中,有一半的數(shù)據(jù)比他大,有一半的數(shù)據(jù)比他小。?如果序列個(gè)數(shù)為奇數(shù),則中間的數(shù)就是中位數(shù),只有一個(gè),如果個(gè)數(shù)為偶數(shù)的話,則中位數(shù)是中間兩位數(shù)的均值,需要找到兩個(gè)數(shù)求平均值,如果個(gè)數(shù)為奇數(shù),其中位數(shù)為((n+1)/2)== ((n+2)/2),對(duì)于偶數(shù),中位數(shù)為分別為((n+2)/2)和(n/2),其中偶數(shù)情況下N/2 == (N+1)/2,因此不論奇數(shù)還是偶數(shù),我們都可以求((n+2)/2和((n+1)/2),然后取平均值。
如果沒(méi)有時(shí)間復(fù)雜度要求的話很簡(jiǎn)單,倆數(shù)組重排列后取中位數(shù)即可,但是題目要求是時(shí)間復(fù)雜度為O(log(m + n))。網(wǎng)上的同志說(shuō)看到時(shí)間復(fù)雜度為log的基本上都是二分法,這個(gè)我之前不知道,水平不夠高??戳艘晃淮笊竦慕夥?#xff0c;明白了。這道題可以這樣來(lái)看,求倆有序數(shù)組的中位數(shù),相當(dāng)于在一個(gè)有序的數(shù)組里找到第K個(gè)數(shù),假設(shè)數(shù)組A的起始搜索位置和數(shù)組B的起始搜索位置分別是i和j,如果起始位置大于數(shù)組長(zhǎng)度的話,說(shuō)明在當(dāng)前數(shù)組已經(jīng)沒(méi)有數(shù)了,這時(shí)候直接去另一個(gè)數(shù)組里取第K個(gè)數(shù)即可。如果K為1的話,返回倆數(shù)組中第一個(gè)值當(dāng)中的最小值即可,如果是其它情況,我們對(duì)K進(jìn)行二分,先找到K/2,假設(shè)K' = K/2,找到則排除一半,再在找另一半即可,首先判斷起始位置加上要找的數(shù)長(zhǎng)度是否超過(guò)數(shù)組長(zhǎng)度,如果超過(guò)的話,這時(shí)候另外一個(gè)數(shù)組(假設(shè)為B)里前K' 個(gè)數(shù)是可以省略的,因?yàn)槲覀円业贙個(gè)數(shù),那么它絕對(duì)不會(huì)在B的K‘ 里面,因?yàn)殚L(zhǎng)度不夠。舉個(gè)例子,數(shù)組A={1},數(shù)組B={0,2,4,6,7,8,9,12},一共9個(gè)數(shù),假設(shè)是有序數(shù)組,我們知道第五個(gè)數(shù)就是中位數(shù),這里我們先二分K,5/2取余 = 2,數(shù)組A和B的初始查找位置都為0,對(duì)于A而言,2大于它的長(zhǎng)度1,這時(shí)候我們可以排除掉數(shù)組B中的前兩個(gè)元素了,因?yàn)榈谖鍌€(gè)數(shù)肯定要在前兩個(gè)數(shù)后面,這時(shí)候我們就排除掉兩個(gè),這時(shí)候需要移動(dòng)B的起始位置,j = j + K',剩下三個(gè),同樣的道理,對(duì)三進(jìn)行二分。還有一種情況是兩個(gè)數(shù)組里從各自的起始位置都存在K‘個(gè)數(shù),這時(shí)候就需要比較A[ i + K' ]和B[ j + K' ],哪個(gè)大則移動(dòng)另外一個(gè)數(shù)組的起始指針K’ 位,相等則移動(dòng)任意一個(gè)。這時(shí)候就排除了K‘,我們只需要遞歸查找第K - K',同理,繼續(xù)二分,K’ = (K - K') / 2; 直到K = 1,或者某個(gè)數(shù)組起始位置超出數(shù)組長(zhǎng)度,這時(shí)候直接返回另一個(gè)數(shù)組里對(duì)應(yīng)K‘即實(shí)我們要找的值。
總的來(lái)說(shuō),思路很巧妙,沒(méi)有經(jīng)過(guò)訓(xùn)練很難短時(shí)間內(nèi)想到。此外就是二分法通常都需要遞歸調(diào)用。
下面是該問(wèn)題的C代碼實(shí)現(xiàn)。
#define MIN(a,b) ((a) > (b) ? (b) : (a))int GetKth(int *nums1, int nums1Size, int start1, int *nums2, int nums2Size, int start2, int k) {int K1, K2;if (start1 + 1 > nums1Size)return nums2[start2 + k - 1];if (start2 + 1 > nums2Size)return nums1[start1 + k - 1];if (k == 1)return MIN(nums1[start1], nums2[start2]);if (start1 + k / 2 > nums1Size)return GetKth(nums1, nums1Size, start1, nums2, nums2Size, start2 + k / 2, k - k / 2);if (start2 + k / 2 > nums2Size)return GetKth(nums1, nums1Size, start1 + k / 2, nums2, nums2Size, start2, k - k / 2);K1 = nums1[start1 + k / 2 - 1];K2 = nums2[start2 + k / 2 - 1];if (K1 < K2)return GetKth(nums1, nums1Size, start1 + k / 2, nums2, nums2Size, start2, k - k / 2);elsereturn GetKth(nums1, nums1Size, start1, nums2, nums2Size, start2 + k / 2, k - k / 2); }double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){int k1 = (nums1Size + nums2Size + 1)/2;int k2 = (nums1Size + nums2Size + 2)/2;//奇數(shù)和偶數(shù)一樣return ((double)GetKth(nums1, nums1Size, 0, nums2, nums2Size, 0, k1) + (double)GetKth(nums1, nums1Size, 0, nums2, nums2Size, 0, k2))/2; }參考目錄:
1.?https://www.cnblogs.com/grandyang/p/4465932.html
=============================================================================================
Linux應(yīng)用程序、內(nèi)核、驅(qū)動(dòng)、后臺(tái)開(kāi)發(fā)交流討論群(745510310),感興趣的同學(xué)可以加群討論、交流、資料查找等,前進(jìn)的道路上,你不是一個(gè)人奧^_^。
?
總結(jié)
以上是生活随笔為你收集整理的leetcode 4. 寻找两个有序数组的中位数,c语言的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 快速排序 递归版本和非递归方法 c代码
- 下一篇: leetcode 5. 最长回文子串 暴