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