一周一演算法 小哼買書

2022-03-13 09:22:45 字數 2177 閱讀 1034

再來看乙個具體的例子《小哼買書》來看看三個排序在應用上的區別和侷限性。 小哼的學校要建立乙個圖書角,老師派小哼去找一些同學做調查,看看同學們都喜歡讀哪些書。小哼讓每個同學寫出乙個自己最想讀的書的isbn號(你知道嗎?每本書都有唯一的isbn號,不信話你去找本書翻到背面看看)。當然有一些好書會有很多同學都喜歡,這樣就會收集到很多重複的isbn號。小哼需要去掉其中重複的isbn號,即每個isbn號只保留乙個,也就說同樣的書只買一本(學校真是夠摳門的)。然後再把這些isbn號從小到大排序,小哼將按照排序好的isbn號去書店去買書。請你協助小哼完成「去重」與「排序」的工作。

輸入有2行,第1行為乙個正整數,表示有n個同學參與調查(n<=100)。第2行有n個用空格隔開的正整數,為每本圖書的isbn號(假設圖書的isbn號在1~1000之間)。

輸出也是2行,第1行為乙個正整數k,表示需要買多少本書。第2行為k個用空格隔開的正整數,為從小到大已排好序的需要購買的圖書isbn號。

例如輸入

10

2040

3267

4020

89300

40015

則輸出

8

1520

3240

6789

300400

最後,程式執行的時間限制為:1秒。

解決這個問題的方法大致有兩種,第一種方法:先將這n個圖書的isbn號去重,再進行從小到大排序並輸出。第二種方法:先從小到大排序,輸出的時候再去重。這兩種方法都可以。

先來看第一種方法。通過第一節的學習我們發現桶排序稍加改動正好可以起到去重的效果,因此我們可以使用桶排序的方法來解決此問題。

#include int

main()

for(i=1;i<=1000;i++) //

依次判斷1~1000這個1000個桶

getchar();getchar();

return0;

}

這種方法的時間複雜度是就是桶排序的時間複雜度為o(n+m)。

第二種方法我們需要先排序再去重。排序我們可以用氣泡排序或者快速排序。

20 40 32 67 40 20 89 300 400 15

將這10個數從小到大排序之後為 15 20 20 32 40 40 67 89 300 400。

接下來,要在輸出的時候去掉重複的。因為我們已經排好序,因此相同的數都會緊挨在一起。只要在輸出的時候,預先判斷一下當前這個數a[i ]與前面乙個數a[i-1]是否相同。如果相同則表示這個數之前已經輸出過了,不同再次輸出。不同則表示這個數是第一次出現需要,則需要輸出這個數。

#include int

main()

//開始氣泡排序

for(i=1;i<=n-1;i++)}}

printf(

"%d

",a[1]); //

輸出第1個數

for(i=2;i<=n;i++) //

從2迴圈到n

getchar();getchar();

return0;

}

這種方法的時間複雜度由兩部分組成,一部分是氣泡排序時間複雜度是o(n2),另一部分是讀入和輸出都是o(n),因此整個演算法的時間複雜度是o(2*n+n2)。相對於n2來說,2*n可以忽略(我們通常忽略低階),最終該方法的時間複雜度是o(n2)。

接下來我們還需要看下資料範圍。每個圖書isbn號都是1~1000之間的整數,並且參加調查的同學人數不超過100,即n<=100。之前已經說過,在粗略計算時間複雜度的時候,我們通常認為計算機每秒鐘大約執行10億次(當然實際情況要更快)。因此以上兩種方法都可以在1秒鐘內計算出解。如果題目圖書isbn號範圍不是在1~1000之間,而是-2147483648~2147483647之間的話,那麼第一種方法就不可行了,因為你無法申請出這麼大陣列來標記每乙個isbn號是否出現過。另外如果n的範圍不是小於等於100而是小於等於10萬,那麼第二種方法的排序部分也不能使用氣泡排序。因為題目要求的時間限制是1秒,使用氣泡排序對10萬個數的排序,計算機需要執行100億次,需要10秒鐘,需要替換為快速排序,快速排序只需要100000×log2100000≈100000×17≈170萬次,這還不到0.0017秒。是不是很神奇,同樣的問題使用不同的演算法竟然有如此之大的時間差距,這就是演算法的魅力!

我們來回顧一下本章三種排序演算法的時間複雜度。桶排序是最快的,它的時間複雜度是o(n+m);氣泡排序是o(n2);快速排序是o(nlogn)。

一周一演算法 演算法7 Dijkstra最短路演算法

上週我們介紹了神奇的只有五行的floyd最短路演算法,它可以方便的求得任意兩點的最短路徑,這稱為 多源最短路 本週來來介紹指定乙個點 源點 到其餘各個頂點的最短路徑,也叫做 單源最短路徑 例如求下圖中的1號頂點到2 3 4 5 6號頂點的最短路徑。與floyd warshall演算法一樣這裡仍然使用...

第一周 周一

寫在前面 小寫字母代表vj順序,大寫字母代表cf實際順序 problem 今天用賭的方式選題做,我以為是拼題,沒想到是一組整題。第 別的比賽,a.b,c的難度適中。做題的時候已經知道是不按順序了,所以沒有開啟a題。瀏覽發現d題題目比較簡單,就開始分析。十分鐘沒有思路後,看了一下rank,轉而去做c題...

每週一演算法 快速排序

public class quicksort 快速排序 public void recquicksort int left,int right public int partitionit int left,int right,long pivot else return leftptr publi...