Мне недавно был задан этот вопрос:
Вам задан массив, который почти сортирован, поскольку каждый из элементов
N
может быть утерян не более чем наk
позиции из правильного упорядоченного порядка. Найдите эффективный по пространству и времени алгоритм для сортировки массива.
У меня есть решение O(N log k)
следующим образом.
Обозначим arr[0..n)
для обозначения элементов массива из индекса 0
(включительно) в N
(исключая).
- Сортировка
arr[0..2k)
- Теперь мы знаем, что
arr[0..k)
находятся в своих окончательных отсортированных позициях... - ... но
arr[k..2k)
все еще может быть потерянk
!
- Теперь мы знаем, что
- Сортировка
arr[k..3k)
- Теперь мы знаем, что
arr[k..2k)
находятся в своих окончательных отсортированных позициях... - ... но
arr[2k..3k)
все еще может быть потерянk
- Теперь мы знаем, что
- Сортировка
arr[2k..4k)
- ....
- Пока вы не сортируете
arr[ik..N)
, тогда все готово!- Этот последний шаг может быть дешевле других шагов, когда осталось меньше
2k
элементов слева.
- Этот последний шаг может быть дешевле других шагов, когда осталось меньше
На каждом шаге вы сортируете не более 2k
элементов в O(k log k)
, помещая по крайней мере элементы k
в свои окончательные отсортированные позиции в конце каждого шага. Есть шаги O(N/k)
, поэтому общая сложность O(N log k)
.
Мои вопросы:
- Оптимален
O(N log k)
? Можно ли это улучшить? - Можете ли вы сделать это без (частично) повторной сортировки одних и тех же элементов?