Знайдіть медіану несортованого масиву за


45

Для того, щоб знайти медіану несортованого масиву, ми можемо зробити міні-кучу в час для елементів, а потім можемо витягти один за одним елементів, щоб отримати медіану. Але такий підхід зайняв би час.n n / 2 O ( n log n )О(нжурналн)нн/2О(нжурналн)

Чи можемо ми зробити це тим чи іншим методом за час? Якщо ми можемо, то як?О(н)



1
@JukkaSuomela Чому б не зробити це швидкою та простою відповіддю (з коротким поясненням одного такого алгоритму, в ідеалі)?
Рафаель

2
Зверніть увагу на відповідну мета-дискусію ; як виявляється, прості пошуки в Інтернеті призводять до відповіді на це питання.
Рафаель

Відповіді:


45

Це особливий випадок алгоритму вибору, який може знайти й найменший елемент масиву з k - половину розміру масиву. Існує реалізація, лінійна в гіршому випадку.кк

Загальний алгоритм відбору

Спочатку давайте подивимось алгоритм, find-kthякий знаходить й найменший елемент масиву:к

find-kth(A, k)
  pivot = random element of A
  (L, R) = split(A, pivot)
  if k = |L|+1, return pivot
  if k ≤ |L|  , return find-kth(L, k)
  if k > |L|+1, return find-kth(R, k-(|L|+1))

Функція split(A, pivot)повертає L,Rтаким чином, що всі елементи Rбільше , ніж pivotта Lвсі інші (мінус один входження pivot). Потім все робиться рекурсивно.

Це в середньому , але O ( п 2 ) в гіршому випадку.О(н)О(н2)

Лінійний гірший випадок: алгоритм медіани медіани

Кращим стрижнем є медіана всіх медіанів підмасивів Aрозміром 5, використовуючи виклик процедури на масив цих медіанів.

find-kth(A, k)
  B = [median(A[1], .., A[5]), median(A[6], .., A[10]), ..]
  pivot = find-kth(B, |B|/2)
  ...

Це гарантує у всіх випадках. Це не так очевидно. Ці слайди Powerpoint корисні як для пояснення алгоритму, так і для складності.О(н)

Зауважте, що більшість часу за допомогою випадкового стрижня відбувається швидше.


Це 5стандарт розміру ? Що робити, якщо розмір A менше 5?
Jayesh

Для будь-якого фіксованого n складність є постійною, якщо вона не є нескінченною. Отже, ви можете використовувати будь-який дійсний алгоритм з обмеженою складністю для такого особливого випадку, навіть якщо це був O (2 ^ n). Для фіксованого n (тобто максимум 4 на випадок), складність становить максимум O (2 ^ 4) = O (1).
v6ak

3
Щодо першого алгоритму: return A[k]невірно (якщо тільки Aне відсортовано, що зробить алгоритм спірним). Якщо splitтрапилося поділити Aтаке, що k = |L| + 1ви досі не знаєте, де знаходиться цей kелемент. Ваш базовий випадок - коли |A| = 1ще потрібно здійснити один з двох рекурсивних дзвінків.
wcochran

2
@NickCaplinger виправлено за допомогою web.archive.org
jmad

1
Чи не найгірший випадок для алгоритму загального вибору O (NlogN)? Навіть якщо рекурсивний виклик залишає лише 10% масиву після кожного дзвінка, то це все-таки логарифм в основі 10.
октавіан

6

н-1/4О(н)

Основна ідея алгоритму - використовувати вибірку. Ми повинні знайти два елементи, які розташовані близько один від одного в упорядкованому порядку масиву і мають середнє значення між ними. Для повної дискусії див. Посилання [MU2017].


[MU2017] Майкл Міценмахер та Елі Упфаль. "Імовірність та обчислення: рандомізація та ймовірнісні методи в алгоритмах та аналізі даних", глава 3, стор. 57-62. Cambridge University Press, друге видання, 2017.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.