Вы можете использовать пропустить список .(Сначала я подумал о связанном списке, но вставка - это O (n), и amit исправил меня пропуском списка. Я думаю, что эта структура данных может быть довольно интересной в вашем случае)
With this data structure, inserting/deleting would take O(ln(k))
and finding the maximum O(1)
Я бы использовал:
- стек, содержащий ваши элементы
- стек, содержащий историю списка пропусков (содержащий k наименьших элементов)
(я понял, что это былоK-й по величине ... элемент. но это в значительной степени та же проблема)
при нажатии (O (ln (k)):
, если элемент меньшеk-й элемент, удалите k-й элемент (O (ln (k)), поместите его в стопку LIFO (O (1)), затем вставьте элемент в список пропуска O (ln (k))
, иначе этонет в списке пропусков, просто поместите его в кучу (O (1))
При нажатии вы добавляете новый список пропусков в историю, так как это похоже на копию при записи, это не займет большечем O (ln (k))
при щелчке (O (1):
вы просто выскочите из обоих стеков
получаякт элЭлемент O (1):
всегда принимает максимальный элемент в списке (O (1))
Все ln (k) являются амортизированной стоимостью.
Пример:
Я возьму тот же пример, что и ваш (в стеке с find-min / find-max более эффективным, чем O (n)):
Предположим, у нас есть стек, и мы добавляем значения 2, 7, 1, 8, 3 и 9 в указанном порядке.и k = 3
Я буду представлять это следующим образом:
[number in the stack] [ skip list linked with that number]
сначала я нажимаю 2,7 и 1 (не имеет смысла искать k-й элемент в спискеменее чем k элементов)
1 [7,2,1]
7 [7,2,null]
2 [2,null,null]
Если я хочу k-й элемент, мне просто нужно взять максимум в связанном списке: 7
теперь я нажимаю 8,3, 9
в верхней части стека, который у меня есть:
8 [7,2,1] since 8 > kth element therefore skip list doesn't change
, затем:
3 [3,2,1] since 3 < kth element, the kth element has changed. I first delete 7 who was the previous kth element (O(ln(k))) then insert 3 O(ln(k)) => total O(ln(k))
затем:
9 [3,2,1] since 9 > kth element
Вот стек, который я получаю:
9 [3,2,1]
3 [3,2,1]
8 [7,2,1]
1 [7,2,1]
7 [7,2,null]
2 [2,null,null]
найти элемент k:
I get 3 in O(1)
теперь я могу получить 9 и 3 (занимает O (1)):
8 [7,2,1]
1 [7,2,1]
7 [7,2,null]
2 [2,null,null]
найти kthэлемент:
I get 7 in O(1)
и нажмите 0 (занимает O (ln (k) - вставка)
0 [2,1,0]
8 [7,2,1]
1 [7,2,1]
7 [7,2,null]
2 [2,null,null]