程式設計之美發帖水王拓展問題

2021-06-25 20:43:35 字數 1286 閱讀 4905

程式設計之美中的「尋找發帖水王」描述的是這麼乙個問題,有乙個id列表,其中有乙個id(水王的id)出現的次數超過了一半,請找出這個id。

書中的思路是每次從列表中刪除兩個不同的id,不影響「水王的id在剩餘id中仍然超過一半」這一事實,因此每次刪除兩個不同的id,直到剩下的所有id都相同,那麼剩下的就是水王的id。

具體程式設計的時候,使用乙個candidate記錄當前猜測的水王id,乙個count記錄其累計次數,然後遍歷整個id列表,對於當前所考查的id,如果和candidate相同,那麼count++,如果不同,那麼count--,這個「count--;」的動作就是「刪除兩個不同的id」在程式中的體現,當count==0時,則更新candidate。這樣呢,每次count--都相當於刪除了兩個不同的id(可能包含水王的,也可能不包含),而每考察乙個id,要麼會做count--的動作,要麼會做count++的動作,兩者必居其一,而由於「水王id超過一半」這一事實,因此count--的次數一定比count++少,因此最後count一定是個正整數,且此時的candidate一定記錄著水王的id。

擴充套件問題是這樣的,如果沒有超級水王了,可是有三個id在列表中出現的次數都超過了1/4,怎麼找出這三個id?

思路是類似的,同樣,每次刪除4個不同的id,不影響「那三個id在剩餘id中出現仍然超過1/4」這一事實,因此我們可以每次刪除4個不同的id,直到剩下3個id為止。具體程式設計中怎麼體現「刪除四個不同id」這一動作呢?我是這樣做的。用candidate[3]記錄三個候選id,用count[3]記錄它們的累積次數,然後遍歷整個id列表,每處理乙個id,若與candidate[i]中的某乙個相同,則count[i]++,若與三個都不同,則說明找到了四個互不相同的id,將三個count[i]--,也就相當於「刪除了四個不同id」,若某乙個count[i]==0,則更新之。

原部落格位址為: 

type candidate1 ;

type candidate2;

type candidate3;

void find(type* id, int n)

else

else

if (ntimes2 == 0)

else

else

else

if (candidate3 == id[i])

else}}

}}}int main()

;find(a,16);

cout << candidate1 <<" " << candidate2 << " " << candidate3 << endl;

return 0;

}

程式設計之美 發帖水王

問題是,在論壇上乙個人非常喜歡發帖,且他發的帖子數目超過了帖子總數的一半,要想快速的找出這個id,怎麼辦?首先可以先把所有帖子按id進行排序,把排序結果存進陣列裡面,然後直接索引n 2即可得到那個id。時間複雜度是n logn.還可以從另外乙個角度來看這個題,因為他的帖子數目超過了總數的一半,因此,...

程式設計之美 發帖水王

題目 分析 最直接的方法,我們可以對所有id排序。然後再掃瞄一遍排好序的id列表,統計各個id出現的次數。如果某個id出現的次數超過總數的一半,那麼就輸出這個id。這個演算法的時間複雜度為o n log2n n 如果id列表已經是有序的,還需要掃瞄一遍整個列表來統計各個id出現的次數嗎?如果乙個id...

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

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