2014-12-11 3 views
2

У меня есть некоторые проблемы. Я должен добавить много разных значений и просто получить только k-й по величине в конце. Как я могу эффективно реализовать это и какой алгоритм использовать?Получить k-ые самые большие значения

+2

Что вы подразумеваете под "must add"? – nop77svk

+1

Если подход: «поместите их в список, отсортируйте список, возьмите верхние элементы k», не решит вашу проблему, которую вам придется немного разработать. Пожалуйста, прочитайте http://stackoverflow.com/help/how-to-ask – reto

+0

Я не хочу хранить все свои значения и в конце концов должен получить только k. –

ответ

6

Алгоритм:

  1. Создать бинарную максимальную кучу, и добавить каждый из первых K значений в кучу.

  2. Для каждого из оставшихся N-K значений, если она больше, чем последнее значение в куче:

    Поставил вместо последнего значения, и пузырек его для того, чтобы прибегать к куче.

  3. Извлеките все значения (K) из кучи в список.


Сложность:

  1. O(K)

  2. O((N-K)×log(K))

  3. O(K×log(K))

Если N-K ≥ K, то общая сложность O((N-K)×log(K)).

Если N-K < K, то общая сложность O(K×log(K)).

+1

Ваш ответ так хорош, как может быть, но. Imvho вы должны попробовать немного «заполнить пробелы» для OP, возможно, короткий пример использования модуля 'heapq' в stdlib ... – gboffi

+0

@gboffi: Какая стандартная библиотека? ОП не указывал язык или среду. Этот ответ так же хорош, как может быть предоставлена ​​информация, предоставленная ОП. –

+0

К сожалению, вы правы ... для записи: Я думал о 'python'. – gboffi

2

(на основе комментариев, которые вы не хотите, чтобы хранить все номера, вы видели ...)

Держите список беговой (отсортированный) из к величине вы видели до сих пор. Когда вы получите новые номера, посмотрите, больше ли он, чем наименьший элемент в списке. Если это так, удалите наименьший элемент и вставьте (отсортированный) новый элемент в список k наибольший. Ваш первоначальный список k (когда вы не видели числа) будет состоять из k записей отрицательной бесконечности.

+1

Вместо сохранения отсортированного списка OP должен поддерживать кучу ... или, может быть, отсортированный список достаточно хорош? Я думаю, что это зависит от 'k' – gboffi

+0

Вы правы, вам нужно только одно, чтобы вы могли эффективно извлекать (или читать) мин и эффективно добавлять новый элемент. Сортировка заключалась в том, чтобы сделать это «интуитивно простым». – TravisJ

+0

Вы тоже правы: куча более эффективна и сложна, отсортированный список более обременителен и прост и, вероятно, подходит для OP. – gboffi

0

Сначала постройте max-heap, используя те элементы, которые являются O (n) временем. затем извлеките k-1 элементов в O (klogn).

+0

Не оптимально: что, если n ужасно велико (т. Е. Не вписывается в память), а k очень мало? Вместо этого: постройте кучу до k элементов и отбросьте минимум каждый раз, когда вы вставляете k + 1-й элемент. – BeyelerStudios

Смежные вопросы