陣列的主元素查詢
阿新 • • 發佈:2020-10-25
描述
已知一個整數序列A=(a0, a1,…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中沒有主元素。假設A中的n個元素儲存在一個一維陣列中,請設計一個儘可能高效的演算法,找出A的主元素。若存在主元素,則輸出該元素;否則輸出-1。
輸入
多組資料,每組資料兩行。第一行為一個整數n,代表陣列中有n個元素。第二行為陣列中的n個元素(元素之間用空格分隔)。當n等於0時,輸入結束。
輸出
每組資料輸出一行,若陣列中存在主元素,輸出主元素的值,若陣列中不存在主元素,則輸出-1。
輸入樣例 1
8 0 5 5 3 5 7 5 5 9 0 5 5 3 5 1 5 7 0 0
輸出樣例 1
5 -1
演算法思路: 即求陣列中最多數的問題,再加一步判斷看c是否>n/2.
演算法的基本思想
該演算法的基本思想就是從前向後掃描陣列元素,標記出一個可能成為主元素的元素Num,然後重新計數,確認Num是否是主元素。
演算法的基本步驟
1、
選取候選的主要元素:依次掃描所給陣列中的每一個整數,將第一個遇到的整數Num儲存到c中,記錄Num出現的次數為1,若遇到的下一個整數仍等於Num,則計算器加1,否則計數器減1,當計數器減到0時,將遇到的下一個整數儲存到c中,計數重新記為1,開始新一輪計數,即從當前位置開始重複上述過程,直到掃描完全部元素。
2、
判斷c中元素是否是真正的主元素:再次掃描該陣列,統計c中元素出現的次數,若大於n/2,則為主元素,否則序列中不存在主元素。
演算法核心程式碼:
int Major(int a[], int n) { int c, count=1; c = a[0]; for (int i=0; i < n; i++) { if (a[i] == c) count++; else { if (count > 0) count--; else{ count = 1; c = a[i]; } } } count = 0; for (int i = 0; i < n; i++) { if (a[i] == c) count++; } if (count > n / 2) return c; else return -1; }
本題提交程式碼:
#include<iostream> using namespace std; int Major(int a[], int n) { int c, count=1; c = a[0]; for (int i=0; i < n; i++) { if (a[i] == c) count++; else { if (count > 0) count--; else { count = 1; c = a[i]; } } } count = 0; for (int i = 0; i < n; i++) { if (a[i] == c) count++; } if (count > n / 2) return c; else return -1; } int main() { while (1) { int n,c; cin >> n; if (n == 0) break; int a[10000]; for (int i = 0; i < n; i++) cin >> a[i]; c = Major(a, n); cout << c << endl; } }