題目描述:
已知一個整數序列A={a0,a1,a2,...an-1} 其中0<=ai<n(0<=i<n).若存在
ap1=ap2=...=apm=x且m>n/2(0<=pk<n,1<=k<=m),則稱x爲A的主元素。如
A={0,5,5,3,5,7,5,5},則5爲主元素,又如A={0,5,5,3,5,1,5,7},則A中沒有
主元素,如有主元素輸出該元素,不然輸出-1. 算法
分析:由於有這個條件0<=ai<n(0<=i<n),咱們能夠天然而然的想到開闢一個n個長度的數組,用下標來代替0,1,2...n-1的值,數組裏面天然就是存儲其出現的次數咯,而後判斷其個數便可,代碼以下:數組
#include<stdio.h> #define N 8 int A[N]; int main() { for(int i=0;i<N;i++){ int k; scanf("%d",&k); A[k]++; } int ok=1; for(int i=0;i<N;i++){ if(A[i]>N/2) { ok = 0; printf("%d\n",i); break; } } if(ok) printf("-1\n"); return 0; }
固然這種思路的時間複雜度爲O(n),空間複雜度爲O(n),能有更好的辦法嗎,將空間複雜度將爲O(1)呢?在王道上看到這樣一種思想,就是用一個count來記錄num,若是下次出現的仍是num,則count加一,不然減一,若爲主元素,則在抵消的過程當中它的count最終是大於0,而不是主元素的話在抵消的過程當中會變爲0。具體算法描述:code
void Majority(int A[],int n){ int i,c,count=1; c = A[0]; for(i=1;i<n;i++){ if(A[i] == c){ count++; }else{ if(count>0) count--; else { c = A[i]; count = 1; } } } if(count>0){ count = 0; for(i=0;i<n;i++){ if(A[i]==c) count++; } } if(count>n/2) printf("%d\n",c); else printf("-1\n"); }
實現程序的時間複雜度爲O(n),空間複雜度爲O(1).it