假设有一个未排序的项目列表,并且我们知道列表中每个项目的初始位置(索引)。现在我们开始执行插入和删除操作。完成所有操作后,我希望能够计算位于第n个位置的商品的新索引。
例如。假设我们有以下列表:
['a', 'x', 'b', 'w', 'e'].
我们执行以下操作(索引从零开始):
新列表为:
['j', 'x', 'b', 'u', 'w']
我想知道该项目在索引3处的新索引('w'-答案是4)。
当然,我总是可以遍历列表并找到'w'的索引-这需要O(N)。
我正在寻找一种算法,该算法将提供“位置n处的项目的新位置是什么”的答案。该算法可以将O(1)计算添加到插入和删除操作中。当被询问时,算法应返回小于O(N)的项目新位置。 (可能是O(log n),如果可能的话甚至是O(1)。
修改 只是更具体些。我正在寻找的算法在完成一组修改后开始。我们可以进行一次创建数据结构的设置,然后可以根据给定的原始位置查询该数据的新位置。假设列表的大小为N,操作数为M。还要假设K = Max(N,M)。
此外,该算法可以假定所有查询都在查找列表中仍然存在的项目。
答案 0 :(得分:0)
修改列表结构以存储每个元素的初始位置,例如存储每个元素的索引,值而不是值的元组:
['a', 'x', 'b', 'w', 'e']
成为
[{'a', 0}, {'x', 1}, {'b', 2}, {'w', 3}, {'e', 4}]
然后运行插入和删除操作,为每个新插入赋予索引-1,以指示该插入不在原始列表中:
[{'j', -1}, {'x', 1}, {'b', 2}, {'u', -1}, {'w', 3}]
现在创建一个等于原始列表大小的数组'newIndexArray',将所有值初始化为-1,然后遍历新列表,从0开始递增一个计数器以跟踪新位置。为每个元素设置:
newIndexArray[elementTuple.Item2] = counter
newIndexArray
现在将包含以下值:
newIndexArray[0] = -1
newIndexArray[1] = 1
newIndexArray[2] = 2
newIndexArray[3] = 4
newIndexArray[4] = -1
-1表示原来位于该位置的元素已被删除。
整个列表的算法为O(N),或者每个元素为O(1)。每次插入和(将索引初始化为-1)会增加O(1)的费用
答案 1 :(得分:0)
这是一种算法,用于每个操作O(log n)
和每个查询O(1)
中。我们将元素存储在implicit treap(或其他类似的笛卡尔树结构)中,该元素允许在O(log n)
中进行插入,删除和按索引访问。完成所有操作后,我们遍历隐式treap并构建元素位置的表。然后,我们可以按照samgak的答案所述,在O(1)
中回答查询。