《編程之美》讀書筆記: 尋找發帖水王的擴展題

最近,零零散散的看了《編程之美》這本書的一兩道題,發現都是挺有趣的題目,書裏面的思路很好,看完後啓發真不少,其中有一道叫“尋找發帖水王”的題目,用一般思路去解決,時間複雜度會是ON * log2N + N)。但換一種簡單的思路卻可以是ON),這對程序來說,在運行效率上應該是質的飛躍了。

原題目如下:http://www.msra.cn/Articles/ArticleItem.aspx?Guid=24dd6639-53d7-4b75-a55e-10eef4f3083e#.

爲了方便說明,貼出題目僞代碼如下:

  

 

 

 

其中最後,有一道擴展題,題目如下:

隨着Tango的發展,管理員發現,超級水王沒有了。統計結果表明,有3個發帖很多的ID,他們的發帖數目都超過了帖子總數目N1/4。你能從發帖ID列表中快速找出他們的ID嗎?

這道題顯然還是用原題中的思路去解決,但問題複雜了,由原來的一個水王,變成了3個,且他們的總數目皆超過總體數的1/4。我的思路如下:

    首先,上題思路是,當遍歷ID與當前ID(candidate變量)不同時,當前ID(candidate變量)所遍歷到的個數減1(nTimes - 1),相同則遍歷數加1,當nTimes等於0時,就說明,當前ID遍歷到的個數爲0或已被抵消爲0,那當前ID就等於新遍歷到的ID,且其遍歷數賦爲1(當然這個新遍歷到的ID可以等於當前),這就意味着,整個遍歷下來,相同的ID都會被累加起來,而不同ID之間會互相抵消,最後剩下來的candidate變量就是灌水王ID,但我們能保證一定是灌水王的ID嗎?讓我們假設一種最極端的狀況就是,所有非灌水王ID都與灌水王ID抵消,但因爲,灌水王佔大於總帖數一半的帖數,故其總遍歷數減去所有帖子數,總會大於0,所以最終返回的condidate變量總會是灌水王的ID。

   有了上題的思路之後,我們就着手於這一題了。上題只需要一個結果,而現在需要3個結果,所以我們考慮數組作爲返回值,同時,上題用到的nTimes,也應改爲一個大小爲3的數組。我們要如何保證最終返回的數組的3個元素就是3個灌水最多的用戶呢?首先分析其所佔比例,各超過1/4,也就是說剩下的其它ID所佔帖數就不足總帖數1/4了。現在我們需要3個變量來記錄當前遍歷過的3個不同的ID,而nTimes的3個元素分別對應當前遍歷過的3個ID出現的個數。如果遍歷中有某個ID不同於這3個當前ID,我們就判斷當前3個ID是否有某個的nTimes爲0,如果有,那這個新遍歷的ID就取而代之,並賦1爲它的遍歷數(即nTimes減1),如果當前3個ID的nTimes皆不爲0,則3個ID的nTimes皆減去1,這也就是解決本文題的關鍵了。由於非水王ID不滿總帖數的1/4,與上題思路相同,所遍歷ID與當前3個ID不同時,就一同抵消(即3個當前ID的nTimes值減1),最終留下來的3個當前ID總會是3個超過1/4的水王ID。

 

具體算法僞代碼如下:(寫的比較複雜,沒有做代碼優化)

   

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章