Lider w zbiorze

Czym jest lider? Określamy tak liczbę, która występuje w zbiorze n-elementowym więcej niż n2 razy. Ponieważ dwie różne liczby nie mogą występować w tym samym zbiorze liczbowym więcej niż n2 razy, lider jest tylko jeden.

Na przykład w zbiorze {1, 4, 6, 1, 1} lider to liczba 1, ponieważ występuje w nim aż 3 razy.

n2=52=2,53>2,5

Natomiast w zbiorze {8, 6, 4, 5, 2, 2} żadna z sześciu liczb nie jest liderem, choć liczba 2 występuje więcej razy niż pozostałe.

Zbiory, które mają lidera, posiadają bardzo ważną właściwość: jeżeli z takiego zbioru usuniemy parę różnych liczb, zbiór ten nadal będzie miał tego samego lidera.

Rozważmy dwa przypadki.

Pierwszy dotyczy usunięcia pary liczb, z której żadna nie jest liderem. Ze zbioru {1, 4, 6, 1, 1} usuwamy liczby 4 oraz 6 i zostajemy z podzbiorem {1, 1, 1}. Ponieważ zbiór ten składa się tylko z jedynek, bardzo łatwo stwierdzić, że lider tego zbioru nie zmienił się i nadal jest nim liczba 1.

W drugim przypadku usuniemy jedną liczbę, która nie jest liderem, i jedną, która nim jest – czyli usuniemy liczby 4 oraz 1. Zostajemy wtedy ze zbiorem {1, 6, 1}, którego liderem nadal jest liczba 1. Ponieważ para, która zostaje wyeliminowana, nie może składać się z tych samych liczb, przypadek, w którym usunięte zostaną dwie liczby lidera, nie zaistnieje.

Algorytm wyboru lidera

Specyfikacja problemu:

Dane:

  • n – liczba naturalna; liczba elementów zbioru zbiór

  • zbior – zbiór liczb naturalnych

Wynik:

  • komunikat wskazujący lidera zbioru lub informujący, że zbiór nie ma lidera

Przykład będzie bazował na zbiorze trzyelementowym, ponieważ łatwiej będzie na nim wskazać pewne zależności.

Wykorzystamy poznaną zależność.

Załóżmy, że pierwsza liczba ze zbioru jest liderem, oraz stwórzmy zmienną, która będzie liczyć wystąpienia lidera. Nazwijmy ją licznik. Skoro zakładamy, że pierwsza liczba jest liderem, zmienną licznik inicjalizujemy wartością 1, ponieważ jedno wystąpienie potencjalnego lidera już nastąpiło. Dodajemy również zmienną, która będzie przechowywała liczbę elementów zbioru.

W pseudokodzie będzie to wyglądało następująco:

Linia 1. zbior ← otwórz nawias klamrowy 1 przecinek 3 przecinek 1 zamknij nawias klamrowy. Linia 2. lider ← zbior otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 3. licznik ← 1. Linia 4. n ← 3.

Następnym krokiem będzie iteracja przez cały zbiór. Ponieważ zakładamy, że pierwszy element zbioru jest liderem, i został on już uwzględniony w zmiennej licznik, możemy go pominąć w pętli i zainicjować zmienną sterującą wartością 1.

Linia 1. zbior ← otwórz nawias klamrowy 1 przecinek 3 przecinek 1 zamknij nawias klamrowy. Linia 2. lider ← zbior otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 3. licznik ← 1. Linia 4. n ← 3. Linia 6. dla i znak równości 1 przecinek 2 przecinek kropka kropka kropka n minus 1 wykonuj.

Naszym celem jest eliminacja par liczb, które nie są takie same. W konsekwencji, jeżeli kolejny element zbioru nie jest taki sam jak dotychczasowy lider (czyli poprzedni element), zmniejszymy wartość zmiennej licznik o jeden. W kolejnej iteracji sprawdzimy, czy zmienna licznik ma wartość 0. Jeżeli warunek jest prawdziwy, przesuniemy lidera na miejsce sprawdzanego elementu, ponieważ oznacza to, że para, która została sprawdzona, zawierała dwie różne liczby – może zatem zostać pominięta. Zobaczmy, jak będzie to wyglądać w pseudokodzie, a następnie przetestujmy działanie tej części algorytmu na przykładzie:

Linia 1. zbior ← otwórz nawias klamrowy 1 przecinek 3 przecinek 1 zamknij nawias klamrowy. Linia 2. lider ← zbior otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 3. licznik ← 1. Linia 4. n ← 3. Linia 6. dla i znak równości 1 przecinek 2 przecinek kropka kropka kropka n minus 1 wykonuj. Linia 7. jeżeli licznik zamknij nawias ostrokątny 0 to. Linia 8. jeżeli lider ← zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy to. Linia 9. licznik ← licznik plus 1. Linia 10. w przeciwnym wypadku. Linia 11. licznik ← licznik minus 1. Linia 12. w przeciwnym wypadku. Linia 13. lider ← zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 14. licznik ← 1.

Dla przykładu rozważmy zbiór {1, 3, 1, 3, 1, 3, 1}, w którym liderem jest 1, i przeanalizujmy działanie algorytmu.

Linia 1. zbior ← otwórz nawias klamrowy 1 przecinek 3 przecinek 1 przecinek 3 przecinek 1 przecinek 3 przecinek 1 zamknij nawias klamrowy. Linia 2. lider ← 1. Linia 3. licznik ← 1. Linia 4. n ← 3.

Wchodzimy w pętlę for, zmienna sterująca i otrzymuje wartość 1. Zmienna licznik ma wartość 1, więc jest większa niż 0.

Czy lider jest równy zbior[i]? Podstawmy wartości i sprawdźmy.

Po podstawieniu wartości wiemy, że wartości tych zmiennych nie są sobie równe.

Odejmujemy od zmiennej sterującej 1 i przechodzimy do kolejnej iteracji. Zmienna licznik jest równa 0, więc przenosimy lidera do zbior[2] czyli 1, a zmiennej licznik przypisujemy wartość 1. Dzięki temu pierwsza para (1, 3) zostaje usunięta, ponieważ liczby w tej parze nie są takie same.

Co się jednak dzieje, gdy para zawiera te same liczby? Ponieważ liczba powtórzyła się, zostaje kandydatem na lidera. Zwiększamy więc wartość zmiennej licznik, która liczy liczbę wystąpień potencjalnego lidera.

W rezultacie działania pętli otrzymamy potencjalnego lidera oraz zmienną licznik. Jeżeli wartość zmiennej licznik wynosi 0, badany zbiór nie ma lidera. Aby mieć pewność, że potencjalny lider jest faktycznie liderem, policzymy liczbę jego wystąpień w zbiorze i sprawdzimy, czy liczba ta jest większa niż długość zbioru podzielona na 2. Dodajmy te zmiany do algorytmu:

Linia 1. zbior ← otwórz nawias klamrowy 1 przecinek 3 przecinek 1 zamknij nawias klamrowy. Linia 2. lider ← zbior otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 3. licznik ← 1. Linia 4. n ← 3. Linia 6. dla i znak równości 1 przecinek 2 przecinek kropka kropka kropka n minus 1 wykonuj. Linia 7. jeżeli licznik zamknij nawias ostrokątny 0 to. Linia 8. jeżeli lider znak równości zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy to. Linia 9. licznik ← licznik plus 1. Linia 10. w przeciwnym wypadku. Linia 11. licznik ← licznik minus 1. Linia 12. w przeciwnym wypadku. Linia 13. lider ← zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 14. licznik ← 1. Linia 16. jeżeli licznik znak równości 0 to. Linia 17. wypisz cudzysłów Zbiór nie ma lidera cudzysłów. Linia 18. zakończ działanie programu. Linia 20. liczba podkreślnik wystapien podkreślnik lidera ← 0. Linia 21. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka n minus 1 wykonuj. Linia 22. jeżeli zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości lider to. Linia 23. liczba podkreślnik wystapien podkreślnik lidera znak równości liczba podkreślnik wystapien podkreślnik lidera plus 1. Linia 25. jeżeli liczba podkreślnik wystapien podkreślnik lidera zamknij nawias ostrokątny n prawy ukośnik 2 to. Linia 26. wypisz cudzysłów Liderem zbioru jest cudzysłów plus lider. Linia 27. w przeciwnym wypadku. Linia 28. wypisz cudzysłów Zbiór nie ma lidera cudzysłów.

Dominującymi operacjami w omawianym rozwiązaniu są porównania w pętlach wykonujących się dla każdego elementu zbioru wejściowego, a zatem złożoność czasowa algorytmu wynosi On.

Implementacja w języku Python

Linia 1. zbior znak równości otwórz nawias kwadratowy 1 przecinek 3 przecinek 1 zamknij nawias kwadratowy. Linia 2. lider znak równości zbior otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 3. n znak równości 1. Linia 5. for i in range otwórz nawias okrągły 1 przecinek len otwórz nawias okrągły zbior zamknij nawias okrągły zamknij nawias okrągły dwukropek. Linia 6. if n zamknij nawias ostrokątny 0 dwukropek. Linia 7. if lider znak równości znak równości zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy dwukropek. Linia 8. n znak równości n plus 1. Linia 9. else dwukropek. Linia 10. n znak równości n minus 1. Linia 11. else dwukropek. Linia 12. lider znak równości zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 13. n znak równości 1. Linia 15. if n znak równości znak równości 0 dwukropek. Linia 16. print otwórz nawias okrągły cudzysłów Zbiór nie ma lidera cudzysłów zamknij nawias okrągły. Linia 17. exit otwórz nawias okrągły zamknij nawias okrągły. Linia 19. liczba podkreślnik wystapien podkreślnik lidera znak równości 0. Linia 20. for i in range otwórz nawias okrągły 0 przecinek len otwórz nawias okrągły zbior zamknij nawias okrągły zamknij nawias okrągły dwukropek. Linia 21. if zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości znak równości lider dwukropek. Linia 22. liczba podkreślnik wystapien podkreślnik lidera plus znak równości 1. Linia 24. if liczba podkreślnik wystapien podkreślnik lidera zamknij nawias ostrokątny len otwórz nawias okrągły zbior zamknij nawias okrągły prawy ukośnik 2 dwukropek. Linia 25. print otwórz nawias okrągły cudzysłów Liderem zbioru jest cudzysłów przecinek lider zamknij nawias okrągły. Linia 26. else dwukropek. Linia 27. print otwórz nawias okrągły cudzysłów Zbiór nie ma lidera cudzysłów zamknij nawias okrągły.