題目要求:設(shè)計(jì)一個(gè)算法,給定一個(gè)10億個(gè)數(shù)字,找出最小的100萬的數(shù)字。假定計(jì)算機(jī)內(nèi)存足以容納全部10億個(gè)數(shù)字。
本題有三種常用的方法,一種是先排序所有元素,然后取出前100萬個(gè)數(shù),該方法的時(shí)間復(fù)雜度為O(nlogn)。很明顯對于10億級別的數(shù)據(jù),這么做時(shí)間和空間代價(jià)太高。
第二種方式是采用選擇排序的方式,首先遍歷10億個(gè)數(shù)字找最小,然后再遍歷一次找第二小,然后再一次找第三小,直到找到第100萬個(gè)。很明顯這種方式的時(shí)間代價(jià)是0()也就是要執(zhí)行10億 * 100萬次,這個(gè)效率一般的服務(wù)器都達(dá)不到。
第三種方式,采用大頂堆來解決,堆的原理在《查找》一章專門介紹過,方法思想是一致的,都是“查小用大堆,查大用小堆”。
首先,為前100萬個(gè)數(shù)字創(chuàng)建一個(gè)大頂堆,最大元素位于堆頂。
然后,遍歷整個(gè)序列,只有比堆頂元素小的才允許插入堆中,并刪除原堆的最大元素。
之后繼續(xù)遍歷剩下的數(shù)字,最后剩下的就是最小的100萬個(gè)。
采用這種方式,只需要遍歷一次10億個(gè)數(shù)字,還可以接受。更新堆的代價(jià)是0(logn),也勉強(qiáng)能夠接受。堆占用的空間是100萬*4,大約為4MB左右的空間就夠了,因此也能接收。
如果數(shù)據(jù)量沒有這么大,也是可以直接使用這三種方式的。文章來源:http://www.zghlxwxcb.cn/news/detail-676015.html
如果將10億數(shù)字換成流數(shù)據(jù),也可以使用堆來找,而且對于流數(shù)據(jù),幾乎只能用堆來做。文章來源地址http://www.zghlxwxcb.cn/news/detail-676015.html
到了這里,關(guān)于算法通關(guān)村第十五關(guān)——從10億數(shù)字中尋找最小的100萬個(gè)數(shù)字的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!