K-тая порядковая статистика

K-тая порядковая статистика

Определение

Пусть дан массив $A$ из $n$ элементов. Тогда $k$-тая порядковая статистика массива $A$ - это такой элемент массива, который стоит на $k$-м месте в отсортированном массиве $A$. Проще говоря:

1
2
3
4
int kthOrderStatistic(vector<int> &a, int k) {
    sort(a.begin(), a.end());
    return a[k - 1];
}

Недетерминированный алгоритм

Алгоритм будет крайне прост и основываться на функции partition из алгоритма быстрой сортировки.

  1. Выберем случайный элемент массива $A$ и назовем его $x$.
  2. Разделим массив $A$ на две части: $L$ - элементы меньше $x$ и $R$ - элементы больше $x$ с помощью функции partition.
  3. Если $k < L$, то рекурсивно вызовем функцию для массива $L$ и $k$.
  4. Если $k = L$, то вернем $x$.
  5. Если $k > L + 1$, то рекурсивно вызовем функцию для массива $R$ и $k - L - 1$.

Такой алгоритм будет работать за $O(n)$ в среднем.

Доказательство По идукции, пусть $T(n)$ - время работы алгоритма для массива размера $n$. Тогда: $T(n) \leq 9n$. С вероятностью $\frac{1}{3}$ случайный элемент $pivot=x$ будет лежать в интервале от $\frac{1}{3}n$ до $\frac{2}{3}n$ после `partition`, а с вероятностью $\frac{2}{3}$ - в во вне. В первом случае при рекурсивном запуске размер массива уменьшится минимум в $\frac{2}{3}$ раза, а во втором - не уменьшится лишь на $1$ элемент (оценка сверху - не уменьшится вовсе). $T(n) \leq n + \frac{1}{3}T(\frac{2}{3}n) + \frac{2}{3}T(n)$ Перенесем всё с $T(n)$ влево и домножим на $\frac{3}{2}$: $T(n) \leq 3n + T(\frac{2}{3}n) \leq 3n + 9 \cdot \frac{2}{3}n = 9n$ что и требовалось доказать.

В C++ есть функция nth_element, которая находит $k$-тую порядковую статистику за $O(n)$ в среднем.

Детерминированный алгоритм

Смотрите в https://cdkrot.me/teaching/2019f-algo1/conspect.pdf.

Ссылки