А вот и решение O (n
) (думаю, прочитать ваше описание было сложно). Это структура данных, которая позволяет 1) обратить подмассив в O (1), 2) получить значение из массива в O (r
), где r
- количество выполненных обращений, 3) найти индекс элемента в O (n
), где n
- длина списка.
Просто сохраните наш массив как обычно и получите список из ReversedRange(imin, imax)
элементов. Обратить часть массива так же просто, как вставить другой элемент в этом списке.
Всякий раз, когда вам нужно получить значение из модифицированного массива по индексу i
, вы просматриваете все ReversedRange
, для которых imin <= i <= imax
, и вычисляете индекс j
, который соответствует исходному индексу массива. Вам нужно проверить r
реверсы, так что это O (r
).
Чтобы получить индекс i
значения v
, просмотрите исходный массив и найдите индекс j
. Совершено за O (n
). Выполните тот же обход ReversedRange
s, только в противоположном направлении, чтобы вычислить i
. Совершено за O (r
), всего O (n
+ r
), что равно O (n
).
* * Пример тысячи тридцать один * ** +1032 +1033 *
Рассмотрим следующий список: 0 1 2 3 4 5 6 7 8 9
. Теперь допустим, что мы изменили индексы формы списка от 1
до 6
, а затем от 0
до 5
. Итак имеем:
I 0 1 2 3 4 5 6 7 8 9
| |
II 0 6 5 4 3 2 1 7 8 9
| |
III 2 3 4 5 6 0 1 7 8 9
Нет, давайте сопоставим индекс i = 2
с исходным массивом. Из графика мы видим, что мы должны получить III(2) = 4
1) since i = 2 is in [0, 5] we calculate
i <- 5 - (i - 0) = 5 - 2 = 3
2) since i = 3 is in [1, 6] we calculate
i <- 6 - (i - 1) = 6 - 2 = 4
3) there are no more ranges, we are done with result 4!