尋找發帖「水王」 《程式設計之美》筆記

2021-09-08 03:00:48 字數 1412 閱讀 7638

首先想到的是乙個最直接的方法,我們可以對所有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嗎?

參考上面的解法,思路如下:

如果每次刪除四個不同的id(不管是否包含發帖數目超過總數1/4的id),那麼,在剩下的id列表中,原先發帖比例大於1/4的id所佔比例仍然大於1/4。可以通過不斷重複這個過程,把id列表中的id總數降低**化為更小的問題),從而得到問題的答案。

**如下:

void find(type* id, int n,type candidate[3])

else if(id[i]==candidate[1])

else if(id[i]==candidate[2])

else if(ntimes[0]==0)

else if(ntimes[1]==0)

else if(ntimes[2]==0)

else

}    return;

}

尋找發帖「水王」 《程式設計之美》筆記

轉至 http hi.baidu.com piaoshi111 blog item 204db32596b8c93e8644f972.html 首先想到的是乙個最直接的方法,我們可以對所有id進行排序。然後再掃瞄一遍排好序的id列表,統計各個id出現的次數。如果某個id出現的次數超過總數的一半,那麼...

程式設計之美 尋找發帖「水王」

描述 直接拍照,懶得打字 此題很容易轉換為,在乙個陣列中,有乙個數出現的次數超過了陣列元素個數的一半,請找出這個元素。方法一 對陣列排序進行排序,利用通常的排序方法,複雜度o nlgn 再遍歷一遍陣列,找出那個元素,複雜度為o n 空間複雜度o 1 方法二 空間換時間吧,在開闢乙個陣列,hash對映...

程式設計之美 尋找發帖「水王」

基礎問題 找出發帖數超過帖子總數一半的id.拓展問題 有三人發帖數都超過了帖子總數目n 的1 4 找出他們的 id.我們可以先排序然後找出中間的那個id 但可以考慮避免排序來改進時間複雜度。每次從列表刪除兩個不相同的id 剩餘的相同 id就是找到的 水王 type find type id,int ...