Я бы сделал это, реализовав "половину" быстрой сортировки.
Рассмотрим исходный набор точек P, где вы ищете «верхние» N элементов по координате Z.
Выберите ось x в P.
Разбиение P на L = {y в P | y
Если N = | U | тогда все готово.
Если N <| U | затем повторить с P: = U. </strong>
В противном случае вам нужно добавить некоторые элементы в U: рекурсивно с N: = N - | U |, P: = L, чтобы добавить оставшиеся элементы.
Если вы выберете свою ось с умом (например, медиана, скажем, пяти случайных выборок), то она будет выполняться за O (n log n) времени.
Хмммм, подумав немного, вы можете вообще избежать создания новых наборов, поскольку по сути вы просто ищете O (n log n) способ найти N-й величайший элемент из исходного набора. Да, я думаю, что это сработает, поэтому вот предложение № 2:
Сделайте обход P, найдя наименьший и наибольший предметы, A и Z, соответственно.
Пусть M - среднее значение A и Z (помните, мы рассматриваем здесь только координаты Z).
Подсчитайте, сколько предметов находится в диапазоне [M, Z], назовите это Q.
Если Q
Если N
Повторять до тех пор, пока мы не найдем M такой, что Q = N.
Теперь пройдитесь по P, удалив все предметы больше или равные M.
Это определенно O (n log n) и не создает никаких дополнительных структур данных (кроме результата).
Howzat