程式設計之美讀書筆記之尋找水王

2021-06-10 10:11:48 字數 2384 閱讀 9282

可以把這個問題轉化為乙個排序和乙個搜尋問題.先把列表轉化為乙個有序列表,然後再遍歷整個列表有序列表.排序演算法不在主題之內,暫時就避而不談.在有序列表尋找出現次數最多的元素這個簡單的演算法跟thunder出的筆試題一模一樣.當時的要求是在乙個有序的字元裡,尋找最多的元素,並統計次數.看看這段簡單的code吧

#include "stdafx.h"

#include #include int thundersearch(char * array, unsigned int number)

else

if (curr >= prev)//當發現當前連續出現的次數大於之前搜尋到得連續次數,重置

}printf("the frequency char is %c\n", array[j]);

return prev;

}int main(int argc, char* argv)

回到剛才的tango尋找水王的問題,上面這段演算法的時間複雜度為o(n),如果算上排序的時間複雜度nlog2(n),那麼整個演算法的時間**度則為o(n+nlog2(n)).當n很大的時候,太影響效率.

這裡的解法用到了分治的策略.如果存在乙個id列表,並且這個列表內有乙個id的次數超過了總數的一半.那麼我們每次刪除兩個不同的id之後剩下的也肯定能滿足有某乙個id的次數超過id總數的一半.由於這這解法不需要排序,所以時間複雜度為o(n)

//#include "stdafx.h"

#include #include char tangofind(char * array, unsigned int number)

else

}return candidate;

}int main(int argc, char* argv)

具體程式設計的時候,使用乙個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?

#include "stdafx.h"

#include #include char tangofind(char * array, unsigned int number)

else

}return candidate;

}void tangofind2(char * array, unsigned int number)

; int ntimes[3] = ;

unsigned int i, j;

bool initcomplete = false;

for (i=0; i < number; i++)

else if ((candidate[1] == 0 || array[i] == candidate[1])

else if (candidate[2] == 0)

}for (j = 0; j < 3; j++)

break;

case 1:

if (array[i] != candidate[j+1] && array[i] != candidate[j-1])

break;

case 2:

candidate[j] = array[i];

ntimes[j] = 1;

break;}}

else

} }}

int main(int argc, char* argv)

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

讀書筆記之程式設計之美 2 3 尋找發帖「水王」

題目的本質就是在一堆id中,找出重複次數大於總數一半的id。由於數量超過總數的一半,所以可以利用這點,讓不同的id之間互相抵消,最後剩下的肯定是總數最大的id。舉個簡單的例子,比如有不同門派的黑幫,有一幫人數大於總共人數的一半,那麼就讓不同門派的人pk,假設結果都是兩敗俱傷,最後還是會剩下沒受傷的人...

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

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

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

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