n個整型元素的陣列a,找出出現次數超過n / 2的元素
阿新 • • 發佈:2021-02-15
技術標籤:# 演算法題
https://www.cnblogs.com/gczr/p/8334459.html
來看這樣一個例子:
5 1 5 4 1 1 3 1 2 1 1
一共11個數字,其中1一共出現了6次。那麼如何快速的找到這個6呢?我們來考慮這樣一個現實生活中的例子:有一群人在打群架,他們每個人有一個編號,代表自己所處的勢力,現在這一群人按照順序依次往廣場中央走,如果廣場內現在有和自己不是一個勢力的人,那麼他就和其中一個同歸於盡,問,最後哪一個勢力的人會獲勝?我們按照這個意思,再來看一下剛才這個例子:
1)勢力5的一個人走進廣場中央,現在廣場中央有一個人,勢力是5
2)勢力1的一個人走進廣場中央,他發現廣場中央有一個勢力是5的人,於是同歸於盡,現在廣場上沒有人
3)勢力5的一個人走進廣場中央,現在廣場中央有一個人,勢力是5
4)勢力4的一個人走進廣場中央,他發現廣場中央有一個勢力是5的人,於是同歸於盡,現在廣場上沒有人
5)勢力1的一個人走進廣場中央,現在廣場有一個人,勢力是1
6)勢力1的一個人走進廣場中央,現在廣場有兩個人,勢力是2
……
可以發現,每一次火拼,勢力最大(也就是出現次數最多的那個數字)的那個每次最多隻會死亡一個。而火拼最多會進行N/2次,出現頻率最高的那個數字最多隻會損失N/2個,而題上告訴我們出現次數已經超過了一半,因此廣場上剩下的那個團伙的編號必然是出現次數做多的那個!
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int findPossibleMain(int A[], int n) {//找出最大勢力 int x = 1;//開始廣場上有一個人 int main = A[0];//這個人的勢力是A[0] for (int i = 1; i < n; i++) {//每一輪各個勢力派一人上廣場PK if (x == 0) { //廣場沒人,此勢力佔領廣場,人數為1 main = A[i]; x = 1; } else { if (main==A[i]) { x++;//廣場上的勢力和進場勢力同屬一個,人數加1 } else //火拼的次數最多為n/2,每次火拼主勢力最多損失1人(損失0人是此場火拼主勢力沒參與) { x--;//不同勢力,火拼後同歸於盡 } } } return main; } int main() { //int A[maxn]={0,5,5,3,5,7,5,5}; //int A[maxn] = { 0,5,5,3,5,1,5,7 }; int n,A[100]; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &A[i]); } int main = findPossibleMain(A, n);//可能的主元素 printf("%d\n", main); int x = 0;//可能的主元素出現的次數 for (int i = 0; i < n; i++) { if (A[i] == main) { x++; } } if (x > n / 2) { printf("所求的元素:%d" , main); } else { printf("沒有這樣的元素"); } return 0; }