Домінуючий елемент#940

Домінуючий елемент (Розбір)

Аналіз алгоритму

Нехай – мажоритарний елемент. Почнемо обробляти вхідні числа. Кожне число, рівне , будемо класти в стек. При надходженні числа, не рівного , будемо вилучати одне число зі стеку. Тоді в кінці обробки даних вершина стеку буде містити мажоритарний елемент.

Спочатку очистимо стек. При обробці чергового елемента :

Якщо по закінченню обробки всіх чисел на вершині стеку є число (якщо стек порожній, то мажоранта немає), то слід перевірити, чи є воно мажоритарним елементом. Для цього слід порахувати, скільки разів число зустрічається в початковому наборі чисел. Якщо зустрічається більше \frac{n}{2} разів, то відповідь стверджувальна.

Оскільки в стеку в будь-який момент часу знаходиться одне число (можливо кілька разів), то змоделюємо стек двома змінними:

Приклад

Розглянемо перший приклад. По закінченню алгоритму в стеці знаходиться 3. Перевіримо, чи є вона мажоритарним елементом. Для цього слід порахувати, скільки разів число 3 зустрічається в початковому масиві. Число 3 в масиві довжиною n = 7 зустрічається 4 рази. Оскільки 4 > \frac{n}{2}, то число 3 є мажоритарним елементом.

Реалізація алгоритму

Вхідну послідовність чисел збережемо в масиві m.

int m[110];

Оголосимо змінні maj і cnt для моделювання стеку:

int maj, cnt;

Читаємо вхідні дані.

scanf("%d",&n);
for(int i = 0; i < n; i++)
    scanf("%d",&m[i]);

Спочатку встановлюємо стек порожнім.

maj = 0; cnt = 0;

Обробляємо вхідні числа, моделюємо роботу стеку.

for(int i = 0; i < n; i++) {
    if (cnt == 0) {maj = m[i]; cnt++;}
    else if (m[i] == maj) cnt++;
    else cnt--;
}

У змінній cnt підрахуємо, скільки разів число maj зустрічається в масиві m.

cnt = 0;
for(int i = 0; i < n; i++)
    if (m[i] == maj) cnt++;

Якщо 2 * cnt > n, то мажорант існує. Інакше ні (res присвоїмо -1).

if(2 * cnt > n) res = maj; else res = -1;

Виводимо відповідь.

printf("%d\n",res);

Java реалізація

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m[] = new int[n];
        for(int i = 0; i < n; i++)
            m[i] = sc.nextInt();
        int maj = 0, cnt = 0;
        for(int i = 0; i < n; i++) {
            if (cnt == 0) {maj = m[i]; cnt++;}
            else if (m[i] == maj) cnt++;
            else cnt--;
        }
        cnt = 0;
        int res;
        for(int i = 0; i < n; i++)
            if (m[i] == maj) cnt++;
        if(2 * cnt > n) res = maj; else res = -1;
        System.out.println(res);
    }
}

Python реалізація

n = int(input())
m = list(map(int, input().split()))

maj = 0
cnt = 0

for num in m:
    if cnt == 0:
        maj = num
        cnt += 1
    elif num == maj:
        cnt += 1
    else:
        cnt -= 1

cnt = 0
for num in m:
    if num == maj: cnt += 1

if 2 * cnt > n: res = maj
else: res = -1

print(res)