Мы будем хранить самый последний минимум непосредственно. Это O (1) пространство.
Мы также будем использовать массив целых чисел, поскольку это, по-видимому, является нашей единственной опцией для пространства переменной длины. Но мы не будем хранить элементы напрямую. Вместо этого, когда мы вставляем элемент, мы сохраним разницу между этим элементом и (предшествующим) минимумом. Когда мы удаляем элемент, мы можем использовать эту разницу для восстановления предыдущего минимума, если это необходимо.
В Python:
class MinStorage:
def __init__(self):
self.offsets = []
self.min = None
def insertElement(self, element):
offset = 0 if self.min is None else (element - self.min)
self.offsets.append(offset)
if self.min is None or offset < 0:
self.min = element
def getMinElement(self):
return self.min
def getLastElement(self):
offset = self.offsets[-1]
if offset < 0:
# Last element defined a new minimum, so offset is an offset
# from the prior minimum, not an offset from self.min.
return self.min
else:
return self.min + offset
def deleteLastElement(self):
offset = self.offsets[-1]
self.offsets.pop()
if len(self.offsets) == 0:
self.min = None
if offset < 0:
self.min -= offset
Вот версия, которая позволяет любому беззнаковое 16-разрядное целое число в качестве элемента, а только хранит беззнаковые 16-битные целые числа в массиве:
class MinStorage:
Cap = 65536
def __init__(self):
self.offsets = []
self.min = None
def insertElement(self, element):
assert 0 <= element < self.Cap
offset = 0 if self.min is None else (element - self.min)
if offset < 0: offset += self.Cap
self.offsets.append(offset)
if self.min is None or element < self.min:
self.min = element
def getMinElement(self):
return self.min
def getLastElement(self):
element = self.__getLastElementUnchecked()
if element < self.min:
# Last element defined a new minimum, so offset is an offset
# from the prior minimum, not an offset from self.min.
return self.min
else:
return element
def deleteLastElement(self):
element = self.__getLastElementUnchecked()
self.offsets.pop()
if len(self.offsets) == 0:
self.min = None
elif element < self.min:
# Popped element defined a new minimum.
self.min = element
def __getLastElementUnchecked(self):
offset = self.offsets[-1]
element = self.min + offset
if element >= self.Cap:
element -= self.Cap
return element
Обратите внимание, что на языке с 16-разрядной арифметикой без знака, которая обертывается при переполнении/потоке, вам не понадобятся проверки и корректировки с использованием self.Cap
. В C (§6.2.5/9) и C++ (§3.9.1/4) необязательная арифметика требуется вести себя по мере необходимости. Однако Python не поддерживает 16-разрядную арифметику без знака.
Связанный список должен сделать это, хотя вам необходимо постоянно отслеживать наименьший элемент после каждой операции (что, кстати, приведет к тому, что 'delete' будет O (n), так как вам нужно будет выполнить полное повторное сканирование чтобы снова найти минимум) – Kevin
Что делает 'delete'? –
«Важная» часть не имеет смысла, поскольку существование метода 'delete' предполагает, что структура должна иметь * не менее * N элементов. И если добавить некоторые накладные расходы для самого структурирования - мы обречены с учетом этой заметки. Я думаю, вы неправильно поняли эту часть. –