Существует асимптотически более быстрый способ решения этой проблемы, но у меня есть серьезные сомнения относительно того, будет ли он работать быстрее на практике, потому что размер вашего окна (10) очень мал.Если вы хотите увеличить этот размер - который я назову k - чтобы он был больше, то вы можете рассмотреть возможность выбора подхода, подобного следующему.
Когда вы используете этот алгоритм, вам необходимоподдерживать окно из k элементов, которое поддерживает две операции:
- Вставить новый элемент, исключая самый старый.
- Возвращает все элементы больше некоторого значения.
Один из способов сделать это - сохранить все ваши элементы в структуре данных, объединяющей сбалансированное двоичное дерево поиска и очередь.Очередь содержит все k элементов, хранящихся в том порядке, в котором они появляются в исходной последовательности, и используется для того, чтобы мы могли вспомнить, какой элемент нужно удалить, когда нам нужно добавить новый элемент.Сбалансированный BST хранит копию каждого из этих элементов, хранящихся в отсортированном порядке.Это означает, что вы можете реализовать описанные выше операции следующим образом:
- Вставить новый элемент, исключив самый старый: Добавить новый элемент в очередь и BST.Затем удалите очередь из очереди, чтобы получить самый старый элемент, затем удалите его из BST.Время выполнения: O (log k), поскольку в BST содержится k элементов.
- Возвращает все элементы, превышающие некоторое значение: Используя BST, найдите самый маленький элемент, по крайней мере, такой же большой, какэто значение в O (log n) времени.Затем отсканируйте BST и перечислите все элементы, по крайней мере, такого размера, как этот элемент.Это занимает время O (z), где z - общее количество найденных совпадений.
В совокупности, если у вас есть n элементов и всего z пар, которые необходимо вставить в базу данных, этоалгоритм займет O (n log k + z) времени.Чтобы увидеть это, обратите внимание, что мы делаем всего n копий операции (1), которая занимает по O (log k) времени.Мы также делаем n копий операции (2), которая занимает O (n log k) времени, чтобы найти преемников, а затем O (z) общее время на всех итерациях, чтобы вывести список всех совпадающих пар.
Асимптотическая среда выполненияэтот алгоритм хорош по сравнению с алгоритмом O (nk), который вы первоначально разместили.Предполагая, что количество совпадений не является «действительно огромным» (скажем, порядка nk), это будет намного быстрее, если вы увеличите n и k.
Если значения, которые вы храните, являются целыми числамив небольшом диапазоне (скажем, 0–10 000) вы можете ускорить это еще больше, заменив сбалансированный BST структурой данных, оптимизированной для целых чисел, например, дерево Ван Эмде Боаса , которое уменьшает это до O(n log log k + z).Опять же, это только быстрее асимптотически , и если вы держите k постоянным на 10, это почти наверняка не стоит.
Надеюсь, это поможет!