假设我有很多元素 每个元素都有一个“位置”字段,它是一个正整数 没有两个元素对字段“position”具有相同的值。
该集合唯一支持的操作是:addElement(newElement,positionAfterElement),其中:
- newElement是要添加的新元素(其位置目前尚不清楚)
- positionAfterElement是集合的现有元素。
该功能将保证:
- position(positionAfterElement)<位置(为newElement)
- 集合中没有其他元素在position(positionAfterElement)和position(newElement)之间的位置
我可以根据需要更改所有元素位置的值,但我希望最小化更改次数(平均)。
我应该如何实现addElement函数?
我可以将更高位置的所有元素推到1但我很确定必须有更好的方法来做到这一点。
感谢大家的帮助。
答案 0 :(得分:3)
使用平衡树。在树的每个节点处,保持其下方项目数的计数(left.count + right.count + 1)。然后,您可以在遍历项目时轻松计算项目的索引。这是操作次数的O(n log n)时间。
答案 1 :(得分:1)
这是一个基本想法:
expected_number_of_elements = 10^6
spread_factor = 100
first element gets position = spread_factor * expected_number_of_element
each following element inserted:
if its inserted in last position, give it the last element's position + spread_factor
if its inserted in the first position, give it the first element's position - spread_factor
otherwise, put it in the middle between its 2 closest neighbors
if you don't have any space left: expand_the_array
expand_the_array:
spread_factor = spread_factor * 10
iterate over all the elements, and multiply position by 10.
扩展数组是一项昂贵的操作,但由于它平均增加了数组的大小(假设您的输入是随机的,而不是由对手制作),您将很少进行此操作。
这个解决方案的主要缺点是,你必须注意int溢出....
答案 2 :(得分:1)
好的,所以这是我用伪代码实现的:
addElement(newElement, positionAfterElement):
p0 <- positionOf(positionAfterElement)
c <- 5
finished <- false
while (not finished):
search for all elements which positions are in the range [p0 + 1, p0 + c]
if there are less than c elements in that range: // the range is not full
adjust position of elements in the range, and position of newElement,
so that
- elements are correctly ordered
- element positions are "evenly spread out" within the range
finished <- true
else: // the range is full
c <- c * 2
end while
end addElement