眾數問題分析
問題描述
•給定一個陣列,找出其中出現次數最多的那個元素(即眾數)。
核心思想
•普遍的解決思路。
•如果我們將所有元素的出現次數進行統計,並從中找出次數中的最大值,那麼,這個最大值對應的元素就是眾數。
•從這一思想出發,我總結出以下兩種演算法:
–演算法1:利用排序演算法統計
–演算法2:利用陣列或雜湊表統計
演算法1
•演算法思路:首先將陣列元素按照大小排序,然後按順序掃描一遍陣列,掃描的同時進行統計。這樣,通過一次排序和一遍掃描,我們就能夠找到眾數。
•關鍵步驟:排序,掃描統計
演算法代價分析
1、時間代價
•由於掃描的時間代價是Θ(n)的,所以演算法的總時間代價主要依賴於排序演算法的代價。
•如果我們選取Θ(nlgn)的排序演算法,最終的時間代價是Θ(nlgn)+Θ(n)= Θ(nlgn)
•Θ(nlgn)是基於比較的排序不可逾越的時間下界,也是該演算法能夠達到的最低代價。
2、空間代價
•掃描統計時,我們只需要三個輔助變數:一個用於計數,一個用於記錄當前出現次數最多的元素的出現次數,一個用於記錄當前出現次數最多的元素。
•所以,如果排序演算法的輔助空間是O(1)的,那麼整個演算法的輔助空間代價就是O(1)的。
改進想法
•思想:改進排序演算法,使得排序演算法在排序的同時就統計出現次數,並記錄次數最多的元素,以及刪除所有重複的元素。這樣,不僅可以減小排序的規模,並且省去了最後掃描的步驟,在一定程度上優化了該演算法。
•然而,雖然改進後的演算法比原始演算法效率高,但是由於其本質仍然是基於比較的排序演算法,所以時間代價還是Θ(nlgn)的,並沒有在數量級上取得突破。
演算法2
•演算法思路:直接統計各元素出現的次數,用某一種線性資料結構儲存統計結果。
•樸素的實現方法:用一個輔助陣列儲存統計結果,統計時用陣列下標對應相應元素。
演算法代價分析
1、時間代價
•用下標對應元素,訪問時間O(1)。順序掃描一遍原陣列,就可以得到統計結果。
•總的時間代價Θ(n)。
演算法代價分析
2、空間代價
•依賴於原陣列中元素的範圍。
•假設我們知道元素集中分佈在寬度為m的區間內,那麼我們就可以開闢大小為m的陣列用於統計。這時,最後使用的輔助空間便是O(m)的。
•然而我們一般並不能確切地知道陣列中數的範圍,或者陣列中元素的分佈非常稀疏(即陣列中有相當比例的空間儲存的統計數為0)。這時,下標連續分佈的、上下界明確的陣列就難以承擔其職責了。
•因此,我們必須改進資料結構,以更加廣泛地適應演算法的需求。
改進想法
•核心思想:採用雜湊表。
•雜湊表的優點:儲存靈活,檢索效率高。
•因此,使用雜湊表能夠有效地替代陣列,實現演算法的功能。
•雜湊表的缺點:空間利用率低。
•據實驗,當雜湊表的負載因子小於0.5時,雜湊表在大部分情況下的檢索長度小於2。但是,如果超過0.5,雜湊表的效能就會急劇下降。
•因此,如果原陣列元素分佈稠密,使用雜湊表的空間效率就要低於使用陣列。
改進後演算法的代價分析
•前提假設:雜湊表的效能良好(負載因子小於0.5)
1、時間代價
•同樣是掃描一遍,然而每一次的平均探查長度大於1。因此,時間效率要比陣列低。
•但是,由於雜湊表效能良好,平均探查長度小於2,所以時間代價依然是O(n)的。
改進後演算法的代價分析
2、空間代價
•如果原陣列中共有m個不同的元素,那麼,由於負載因子小於0.5,因此雜湊表的大小至少是2m。空間效率低於元素稠密時的陣列,但是可能會遠高於資料稀疏時的陣列。
演算法比較
•這份報告中主要介紹了兩種演算法思想。他們各有利弊,對比如下:
1、基於排序的演算法
•時間代價:Θ(nlgn)
•空間代價:O(1)
2、直接統計的演算法
•時間代價:Θ(n)
•空間代價:Ω(m)
•從以上對比,我們可以看出:演算法2是利用空間換時間,雖然使用了大量的輔助空間,但是時間代價要遠低於演算法1。
•我們的演算法設計,就是一個權衡利弊的過程。很多時候,時間和空間不可兼得,那麼,我們就要根據使用者的需求選擇合適的演算法,以實現時間更快或者空間更省。
•而對於演算法2,我們同樣面臨著選擇:使用陣列還是使用雜湊表。這一選擇基於陣列元素的分佈:如果陣列元素分佈稠密,使用陣列自然是又快又省;可是,如果分佈稀疏或是不確定,雜湊表的靈活性就派上了用場。
•因此,除了使用者需求,我們面對的資料本身也左右著我們的選擇。
•在實際應用中,眾數問題一般用於對大量資料的統計。
•下面舉一些例項,來探討實際問題中眾數問題的解決方案。
例項1
•選票統計
•data*+=,“張三”,“李四”,“李四”,“張三”,“李四”,“李四”,“棄權”,“李四”,“張三”,“李四”,“張三”,“棄權”,“張三”……-
•資料規模大,資料範圍有限,顯然用陣列更為方便。
例項2
•在一些科學實驗中,我們要對實驗資料進行統計和分析,這時眾數只是我們研究的一部分,還有其他方面(例如分佈情況)需要研究。這時,我們希望一次運算得到的資訊量更多。
•這時我們也需要用陣列。
010203040506070809010~2020~3030~4040~50資料:23.1,14.6,39.7,32.0,12.2……
範圍
10~20
20~30
30~40
40~50
分佈數
20
28
90
21
例項3
•假設1:有海量的資料需要統計,如果要排序只能通過外排序。
•假設2:硬碟空間足夠用(操作過程中不必考慮空間開銷)
•這時有一個使用者需求,要得到這些資料的眾數。
•如果用排序,我們必須考慮外排序可怕的時間代價。
•如果用陣列或雜湊表,雖然會佔用額外的硬碟儲存空間。但是,如果這些資料需要經常增刪,並且需要經常呼叫取眾數操作,那麼,儲存這些統計結果將帶來極大的方便。
總結
•解決眾數問題主要有兩種演算法思想,其中演算法2可以使用兩種不同的輔助資料結構。這三者本身都是解決眾數問題的很好的辦法,他們之間並無優劣。具體實現時,我們選擇哪種方法,要依賴於我們對時空的權衡,以及資料本身的性質。
•眾數問題雖然很簡單,但是從中折射出的關於時空權衡的考慮,是演算法設計時會普遍遇到的問題,值得大家討論和思考。
//眾數問題
/*
問題描述:
給定含有n個元素的多重集合S,每個元素在S中出現的次數成為該元素的重數。多重
集S中重數最大的元素稱為眾數。
例如, S = {1,2,2,2,3,5}。
多重集s的眾數是2,其重數為3。
程式設計任務:
對於給定的由n個自然陣列成的多重集S,程式設計計算S的眾數及其重數。
*/
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <map>
using namespace std;
int main()
{
ifstream input("input.txt",ios::in);
ofstream output("output.txt",ios::out);
if (!input)
{
cerr<<"inputfile could not be opened"<<endl;
exit(1);
}
map<int,int> number_count;
int number;
while(input >>number)
{
++number_count[number];
}
map<int,int>::iterator map_it = number_count.begin();
map_it++;
int key = map_it->first;
int maxcount = map_it->second;
while(map_it != number_count.end())
{
if (maxcount < map_it->second)
{
maxcount = map_it->second;
key = map_it->first;
}
++map_it;
}
output<<key<<endl<<maxcount;
return 0;
}
相關文章
- ACM 眾數問題ACM
- 分治演算法-眾數問題演算法
- 演算法設計--眾數和重數問題(分治法)演算法
- 數對數目;及LIS問題分析
- 演算法題:求眾數演算法
- Leetcode刷題——求眾數LeetCode
- ClientAbortException 問題分析clientException
- 【演算法解題報告】求眾數演算法
- (二)涉眾分析
- Rabbimtmq unack問題分析MQ
- JVM 問題分析思路JVM
- 抽獎問題分析
- 演算法面試題彙總_2求眾數演算法面試題
- 雙模數問題 題解
- MySQL訪問受限的問題分析MySql
- Oracle RAC引數設定優先順序別問題分析Oracle
- SQL星期數問題SQL
- Goldegate 追數問題Go
- 組合數問題
- LeetCode每日一題:求眾數(No.169)LeetCode每日一題
- 填報 - 分片問題分析
- Spring框架問題分析Spring框架
- MySQL 死鎖問題分析MySql
- OOM分析之問題一)OOM
- HDFS Decommission問題分析
- sonar常見問題分析
- 問題賬戶需求分析
- Sqlserver分析死鎖問題SQLServer
- 線上死鎖問題分析
- ActiveMQ問題分析和解決MQ
- recyclebin造成的問題分析
- 宣告變數的問題變數
- goroutine的次數問題Go
- 字串位元組數問題字串
- Oracle Extent引數問題Oracle
- 公眾號 - 解決所有測試中的CORS問題CORS
- 如何分析報表效能問題
- OOM分析之問題定位(二)OOM