首先想到的是乙個最直接的方法,我們可以對所有
id進行排序。然後再掃瞄一遍排好序的
id列表,統計各個
id出現的次數。如果某個
id出現的次數超過總數的一半,那麼就輸出這個
id。這個演算法的時間複雜度為o(
n* log2
n + n)。
如果id
列表已經是有序的,還需要掃瞄一遍整個列表來統計各個
id出現的次數嗎?
如果乙個
id出現的次數超過總數
n的一半。那麼,無論水王的
id是什麼,這個有序的
id列表中的第n/2
項(從0
開始編號)一定會是這個
id(讀者可以試著證明一下)。省去重新掃瞄一遍列表,可以節省一點演算法耗費的時間。如果能夠迅速定位到列表的某一項(比如使用陣列來儲存列表),除去排序的時間複雜度,後處理需要的時間為o(
1)。但上面兩種方法都需要先對
id列表進行排序,時間複雜度方面沒有本質的改進。能否避免排序呢?
如果每次刪除兩個不同的
id(不管是否包含「水王」的
id),那麼,在剩下的
id列表中,「水王」
id出現的次數仍然超過總數的一半。看到這一點之後,就可以通過不斷重複這個過程,把
id列表中的
id總數降低**化為更小的問題),從而得到問題的答案。新的思路,避免了排序這個耗時的步驟,總的時間複雜度只有o(
n),且只需要常數的額外記憶體。偽**如下:
**清單
2-8
type find(type* id, int n)
else
}return candidate;}
在這個題目中,有乙個電腦科學中很普遍的思想,就是如何把乙個問題轉化為規模較小的若干個問題。分治、遞推和貪心等都是基於這樣的思路。在轉化過程中,小的問題跟原問題本質上一致。這樣,我們可以通過同樣的方式將小問題轉化為更小的問題。因此,轉化過程是很重要的。像上面這個題目,我們保證了問題的解在小問題中仍然具有與原問題相同的性質:水王的id在
id列表中的次數超過一半。轉化本身計算的效率越高,轉化之後問題規模縮小得越快,則整體演算法的時間複雜度越低。
隨著tango
的發展,管理員發現,「超級水王」沒有了。統計結果表明,有
3個發帖很多的
id,他們的發帖數目都超過了帖子總數目n的
1/4。你能從發帖
id列表中快速找出他們的
id嗎?
相關資源:
《程式設計之美》編輯部
|
《程式設計之美》豆瓣
|
《程式設計之美》互動網購買
|
作者blog
作者豆瓣
BOP 尋找發貼 水王
尋找發貼 水王 中擴充套件題為 隨著tango的發展,管理員發現,超級水王 沒有了。統計結果表明,有3個發帖很多的id,他們的發帖數目都超過了帖子總數目n的1 4。你能從發帖id列表中快速找出他們的id嗎?解答 這道題顯然還是用原題中的思路去解決,但問題複雜了,由原來的乙個水王,變成了3個 首先,我...
微軟《程式設計之美》 尋找發貼「水王」 及 其擴充套件問題
原始問題 一種較好的思路 如果每次刪除兩個不同的id 不管是否包含 水王 的id 那麼,在剩下的id列表中,水王 id出現的次數仍然超過總數的一半。看到這一點之後,就可以通過不斷重複這個過程,把id列表中的id總數降低 化為更小的問題 從而得到問題的答案,總的時間複雜度只有o n 且只需要常數的額外...
尋找小水王
一 題目 三人行設計了乙個灌水論壇。資訊學院的學生都喜歡在上面交流灌水,傳說在論壇上有乙個 水王 他不但喜歡發帖,還會回覆其他id發的每個帖子。坊間風聞該 水王 發帖數 發現水王沒有了,但是統計結果表明,有三個發帖很多的id。據統計他們的發帖數量超過了1 4,你能從發帖列表中快速的找到他們嗎?二 i...