題目:某公司有幾萬名員工,請完成乙個時間複雜度為o(n)的演算法對該公司員工的年齡作排序,可使用o(1)的輔助空間。
分析:排序是面試時經常被提及的一類題目,我們也熟悉其中很多種演算法,諸如插入排序、歸併排序、氣泡排序,快速排序等等。這些排序的演算法,要麼是o(n2)的,要麼是o(nlogn)的。可是這道題竟然要求是o(n)的,這裡面到底有什麼玄機呢?
題目特別強調是對乙個公司的員工的年齡作排序。員工的數目雖然有幾萬人,但這幾萬員工的年齡卻只有幾十種可能。上班早的人一般也要等到將近二十歲才上班,一般人再晚到了六七十歲也不得不退休。
由於年齡總共只有幾十種可能,我們可以很方便地統計出每乙個年齡裡有多少名員工。舉個簡單的例子,假設總共有5個員工,他們的年齡分別是25、24、26、24、25。我們統計出他們的年齡,24歲的有兩個,25歲的也有兩個,26歲的乙個。那麼我們根據年齡排序的結果就是:24、24、25、25、26,即在表示年齡的陣列裡寫出兩個24、兩個25和乙個26。
想明白了這種思路,我們就可以寫出如下**:
void sortages(int ages, int length)
if(ages == null || length <= 0)
return;
const int oldestage = 99;
int timesofage[oldestage + 1];
for(int i = 0; i <= oldestage; ++ i)
timesofage[i] = 0;
for(int i = 0; i < length; ++ i)
int age = ages[i];
if(age < 0 || age > oldestage)
throw new std::exception("age out of range.");
++ timesofage[age];
int index = 0;
for(int i = 0; i <= oldestage; ++ i)
for(int j = 0; j < timesofage[i]; ++ j)
ages[index] = i;
++ index;
在上面的**中,允許的範圍是0到99歲。陣列timesofage用來統計每個年齡出現的次數。某個年齡出現了多少次,就在陣列ages裡設定幾次該年齡。這樣就相當於給陣列ages排序了。該方法用長度100的整數陣列輔助空間換來了o(n)的時間效率。由於不管對多少人的年齡作排序,輔助陣列的長度是固定的100個整數,因此它的空間複雜度是個常數,即o(1)。
本文已經收錄到《劍指offer——名企面試官精講典型程式設計題》一書中,有改動,書中的分析講解更加詳細。歡迎關注。
或者與我討論。謝謝。
時間複雜度為O(n)的排序演算法
我們常用的幾種排序演算法,氣泡排序,選擇排序,它們已經是相對比較簡單,穩定的排序演算法了,但是它們時間複雜度為o n n 基本都要用到兩層迴圈,今天我就像大家介紹一種簡單,只用一層for迴圈,時間複雜度為o n 的排序演算法。樣例輸入 1 4 5 6 3 4 2 8 9 1 樣例輸出 1 1 2 3...
時間複雜度為O n t 的排序
剛在csdn論壇上看到乙個 關於1 n自然數排序的華為面試題 的帖子,勾起了我的回憶 我大二時有段時間閒得沒事幹,想做乙個int型的陣列排序,達到時間複雜度為o n 的目的,同學都因為n log2 n 說這不可能,但自己做完後感覺不錯,雖做不到o n 但自認為時間複雜度為o n t 大家鑑別鑑別是不...
實現排序演算法,時間複雜度為O n
我們常用的排序氣泡排序 o n 2 快速排序o nlogn 堆排序o nlogn 選擇排序o n 2 我們常用的排序都不符合時間複雜度的要求 經常聽說乙個說法 用空間代替時間 現在要排序的陣列為陣列 a 例如a陣列裡面有 1,1,2,2,3,3,2,2,5,5.等等很多無序的數字 那麼我們申請乙個陣...