海量數據(一)

1. 有1億個浮點數,如果找出期中最大的10000個?

  • 最容易想到的方法是將數據全部排序,然后在排序后的集合中進行查找,最快的排序算法的時間復雜度一般為O(nlogn),如快速排序。但是在32位的機器上,每個float類型占4個字節,1億個浮點數就要占用400MB的存儲空間,對于一些可用內存小于400M的計算機而言,很顯然是不能一次將全部數據讀入內存進行排序的。其實即使內存能夠滿足要求(我機器內存都是8GB),該方法也并不高效,因為題目的目的是尋找出最大的10000個數即可,而排序卻是將所有的元素都排序了,做了很多的無用功。

?

  • 第二種方法為局部淘汰法,該方法與排序方法類似,用一個容器保存前10000個數,然后將剩余的所有數字——與容器內的最小數字相比,如果所有后續的元素都比容器內的10000個數還小,那么容器內這個10000個數就是最大10000個數。如果某一后續元素比容器內最小數字大,則刪掉容器內最小元素,并將該元素插入容器,最后遍歷完這1億個數,得到的結果容器中保存的數即為最終結果了。此時的時間復雜度為O(n+m^2),其中m為容器的大小,即10000。

?

  • ?第三種方法是分治法,將1億個數據分成100份,每份100萬個數據,找到每份數據中最大的10000個,最后在剩下的100*10000個數據里面找出最大的10000個。如果100萬數據選擇足夠理想,那么可以過濾掉1億數據里面99%的數據。100萬個數據里面查找最大的10000個數據的方法如下:用快速排序的方法,將數據分為2堆,如果大的那堆個數N大于10000個,繼續對大堆快速排序一次分成2堆,如果大的那堆個數N大于10000個,繼續對大堆快速排序一次分成2堆,如果大堆個數N小于10000個,就在小的那堆里面快速排序一次,找第10000-n大的數字;遞歸以上過程,就可以找到第1w大的數。參考上面的找出第1w大數字,就可以類似的方法找到前10000大數字了。此種方法需要每次的內存空間為10^6*4=4MB,一共需要101次這樣的比較。

?

  • 第四種方法是Hash法。如果這1億個數里面有很多重復的數,先通過Hash法,把這1億個數字去重復,這樣如果重復率很高的話,會減少很大的內存用量,從而縮小運算空間,然后通過分治法或最小堆法查找最大的10000個數。

?

  • 第五種方法采用最小堆。首先讀入前10000個數來創建大小為10000的最小堆,建堆的時間復雜度為O(mlogm)(m為數組的大小即為10000),然后遍歷后續的數字,并于堆頂(最小)數字進行比較。如果比最小的數小,則繼續讀取后續數字;如果比堆頂數字大,則替換堆頂元素并重新調整堆為最小堆。整個過程直至1億個數全部遍歷完為止。然后按照中序遍歷的方式輸出當前堆中的所有10000個數字。該算法的時間復雜度為O(nmlogm),空間復雜度是10000(常數)。

?

參考資料:

1.?海量數據處理 - 10億個數中找出最大的10000個數(top K問題)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385247.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385247.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385247.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

1018 錘子剪刀布 (20 分)

大家應該都會玩“錘子剪刀布”的游戲:兩人同時給出手勢,勝負規則如圖所示: 現給出兩人的交鋒記錄,請統計雙方的勝、平、負次數,并且給出雙方分別出什么手勢的勝算最大。 輸入格式: 輸入第 1 行給出正整數 N…

1019 數字黑洞 (20 分)

給定任一個各位數字不完全相同的 4 位正整數,如果我們先把 4 個數字按非遞增排序,再按非遞減排序,然后用第 1 個數字減第 2 個數字,將得到一個新的數字。一直重復這樣做,我們很快會停在有“數字黑洞”之稱的 6174&…

61. 旋轉鏈表

給定一個鏈表,旋轉鏈表,將鏈表每個節點向右移動 k 個位置,其中 k 是非負數。 示例 1: 輸入: 1->2->3->4->5->NULL, k 2 輸出: 4->5->1->2->3->NULL 解釋: 向右旋轉 1 步: 5->1->2->3->4->NULL…

1020 月餅 (25 分)

月餅是中國人在中秋佳節時吃的一種傳統食品,不同地區有許多不同風味的月餅。現給定所有種類月餅的庫存量、總售價、以及市場的最大需求量,請你計算可以獲得的最大收益是多少。 注意:銷售時允許取出一部分庫存。樣例給出的情形是這樣的&#x…

2. 二叉樹的深度

題目描述 輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。 /* struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(in…

1021 個位數統計 (15 分

給定一個 k 位整數 1 (0, ,, d?k?1??>0),請編寫程序統計每種不同的個位數字出現的次數。例如:給定 0,則有 2 個 0,3 個 1,和 1 個 3。 輸入格式: 每個輸入包含 1 個測試用例,即一個不超過…

【牛客網】X游戲

題目:X游戲 題目描述 我們稱一個數 X 為好數, 如果它的每位數字逐個地被旋轉 180 度后,我們仍可以得到一個有效的,且和 X 不同的數。要求每位數字都要被旋轉。 如果一個數的每位數字被旋轉以后仍然還是一個數字, 則這個數是有效…

1022 D進制的A+B (20 分)

輸入兩個非負 10 進制整數 A 和 B (≤)&#xff0c;輸出 AB 的 D (1)進制數。 輸入格式&#xff1a; 輸入在一行中依次給出 3 個整數 A、B 和 D。 輸出格式&#xff1a; 輸出 AB 的 D 進制數。 輸入樣例&#xff1a; 123 456 8輸出樣例&#xff1a; 1103 #include<cstdio>…

3. 二進制中1的個數

題目描述 輸入一個整數&#xff0c;輸出該數二進制表示中1的個數。其中負數用補碼表示。 class Solution { public:int NumberOf1(int n) {int count 0; for(int i 0; i < 32; i){if(n & (1 << i))count;}return count;} };

1023 組個最小數 (20 分)

給定數字 0-9 各若干個。你可以以任意順序排列這些數字&#xff0c;但必須全部使用。目標是使得最后得到的數盡可能小&#xff08;注意 0 不能做首位&#xff09;。例如&#xff1a;給定兩個 0&#xff0c;兩個 1&#xff0c;三個 5&#xff0c;一個 8&#xff0c;我們得到的最…

C++中重載、重寫(覆蓋)和隱藏的區別實例分析

1.重載&#xff1a;重載從overload翻譯過來&#xff0c;是指同一可訪問區內被聲明的幾個具有不同參數列&#xff08;參數的類型&#xff0c;個數&#xff0c;順序不同&#xff09;的同名函數&#xff0c;根據參數列表確定調用哪個函數&#xff0c;重載不關心函數返回類型。 示…

1024 科學計數法 (20 分

科學計數法是科學家用來表示很大或很小的數字的一種方便的方法&#xff0c;其滿足正則表達式 [-][1-9].[0-9]E[-][0-9]&#xff0c;即數字的整數部分只有 1 位&#xff0c;小數部分至少有 1 位&#xff0c;該數字及其指數部分的正負號即使對正數也必定明確給出。 現以科學計數法…

static、const用法

一、static用法 C的static有兩種用法&#xff1a;面向過程程序設計中的static和面向對象程序設計中的static。前者應用于普通變量和函數&#xff0c;不涉及類&#xff1b;后者主要說明static在類中的作用。 一、面向過程設計中的static 1、靜態全局變量&#xff1a;在全局變量前…

1025 反轉鏈表 (25 分

給定一個常數 K 以及一個單鏈表 L&#xff0c;請編寫程序將 L 中每 K 個結點反轉。例如&#xff1a;給定 L 為 1→2→3→4→5→6&#xff0c;K 為 3&#xff0c;則輸出應該為 3→2→1→6→5→4&#xff1b;如果 K 為 4&#xff0c;則輸出應該為 4→3→2→1→5→6&#xff0c;即…

1026 程序運行時間 (15 分

要獲得一個 C 語言程序的運行時間&#xff0c;常用的方法是調用頭文件 time.h&#xff0c;其中提供了 clock() 函數&#xff0c;可以捕捉從程序開始運行到 clock() 被調用時所耗費的時間。這個時間單位是 clock tick&#xff0c;即“時鐘打點”。同時還有一個常數 CLK_TCK&…

【C++基礎】常見面試問題(二)

1. 指針和引用的區別 指針保存的是所指對象的地址&#xff0c;引用是所指對象的別名&#xff0c;指針需要通過解引用間接訪問&#xff0c;而引用是直接訪問指針可以改變地址&#xff0c;從而改變所指的對象&#xff0c;而引用必須從一而終&#xff1b;引用在定義的時候必須初始…

1028 人口普查 (20 分)

某城鎮進行人口普查&#xff0c;得到了全體居民的生日。現請你寫個程序&#xff0c;找出鎮上最年長和最年輕的人。 這里確保每個輸入的日期都是合法的&#xff0c;但不一定是合理的——假設已知鎮上沒有超過 200 歲的老人&#xff0c;而今天是 2014 年 9 月 6 日&#xff0c;所…

static關鍵字用法

static修飾局部變量 靜態局部變量存儲在全局靜態區生存期為整個程序生命周期&#xff0c;但是其作用域仍與自動變量相同&#xff0c;只能在定義該變量的函數內使用該變量。退出該函數后&#xff0c;盡管該變量還繼續存在&#xff0c;但不能使用它。靜態局部變量若在聲明時未賦以…

1029 舊鍵盤 (20 分)

舊鍵盤上壞了幾個鍵&#xff0c;于是在敲一段文字的時候&#xff0c;對應的字符就不會出現。現在給出應該輸入的一段文字、以及實際被輸入的文字&#xff0c;請你列出肯定壞掉的那些鍵。 輸入格式&#xff1a; 輸入在 2 行中分別給出應該輸入的文字、以及實際被輸入的文字。每段…

volatile、const的用法

1. volatile 訪問寄存器要比訪問內存要塊&#xff0c;因此CPU會優先訪問該數據在寄存器中的存儲結果&#xff0c;但是內存中的數據可能已經發生了改變&#xff0c;而寄存器中還保留著原來的結果。為了避免這種情況的發生將該變量聲明為volatile&#xff0c;告訴CPU每次都從內存…