Нет лучшего решения, чем выполнение каждого из описанных запросов быстрее, чем O(n)
, где n - это число элементов вашего массива последовательно в несортированном массиве, когда вы описываете свою проблему.Это потому, что вы должны учитывать каждый элемент в массиве для ваших запросов.Проблема в том, что у вас нет информации о ваших данных, поэтому вы никогда не будете знать, где проверить, чтобы сделать вещи быстрее.
Если вы сделаете много запросов, вы можете провести некоторую оптимизацию, отсортировав свой массив и сохранив его отсортированным.Хотя сортировка сначала займет O(n log(n))
(Quicksort, Mergesort), она позволит вам выполнить запрос в O(log(n))
(или в худшем случае O(n)
), используя модифицированный бинарный поиск (найдите первый наименьший элемент в вашем диапазоне, а затем возьмитеследующие х элементов).(Если вы используете библиотечную сортировку, такую как qsort, вы будете сортировать что-то вроде 1.3 nlog (n), что действительно хорошо)
Это также позволит вам быстрее выполнять обновление, поскольку вы снова можете использовать BSearch длядобраться до значений, которые вы ищете.Здесь знание о данных важно.Если ваш декремент не сильно изменит порядок (проверьте элементы case), то это более эффективно в долгосрочной перспективе.
Если ваш массив отсортирован, вы также можете эффективно сортировать после Q1, просто учитываяэлементы слева от вашего первого элемента больше или равны х.Если некоторые из этих элементов теперь больше, чем некоторые из ваших элементов, то при уменьшении вы можете найти границу между ними и выполнить обмен между меньшими и большими областями после Q1 (умная сортировка, используя информацию, имеющуюся в ваших данных).
Если вы не должны сортировать свои данные (для целей построения графиков или около того), то линейное время - лучшее, на что вы можете надеяться.Кроме того, сортировка не нужна, если ваш массив небольшой, он будет излишним и не принесет заметных улучшений.И, честно говоря, линейное время действительно хорошо на современных компьютерах.