我需要设计一个支持以下内容的数据结构:
getMinElement
,getLastElement
,insertElement
,deleteLastElement
- 在O(1)
运行时间内。
存储器受n (非O(n))的限制,即您可以在给定时刻保留最多n个元素。再加上O(1)记忆。
(重要的是:指针也被视为1,因此链接列表是不可能的。)
示例:
insert(6)
min() -> 6
insert(10)
insert(5)
min() -> 5
insert(7)
delete()
min() -> 5
delete()
min() -> 6
答案 0 :(得分:4)
我们会直接存储最近的最小值。这是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位算术。
答案 1 :(得分:1)
使用存储插入值和当前最小值的堆栈。插入(推送)值时,通过将值与当前最小值进行比较,以及从堆栈顶部删除(弹出)一个查看当前最小值的值,可以更新当前最小值。
答案 2 :(得分:0)
如果您可以假设类似&#34;数据的范围是0到255(int8)&#34;,并且您可以存储精度两倍的整数(int16),那么您可以存储&#34;累计最低值&#34;在高位字节和低位字节的数据点。除了这样的事情之外,我不相信这可以在你给出的限制范围内实现。