假设我有一个包含以下字段的对象列表(或散列图等,无论是什么使得这个最快):名称,添加的时间和删除的时间。给我的清单已经按时间排序了。现在,给定时间T,我想过滤(从列表中删除)列表中的所有对象,其中: 时间T大于对象的移除时间或者T T小于对象的时间。 因此,在处理之后,列表应该只包含T落在由添加的时间和删除时间指定的范围内的对象。
我知道我可以通过浏览每个单独的对象在O(n)时间内轻松完成此操作,但我想知道是否有更有效的方法考虑列表已经按第一个谓词排序(时间已删除)。
*此外,我知道我可以轻松删除时间被删除小于T的所有对象,因为列表是预先排序的(可能在O(log n)时间内,因为我进行二分查找以找到小于和的第一个元素然后删除列表的第一部分直到该对象。)
(不相关的附加信息:我将使用C ++来编写任何代码)
答案 0 :(得分:1)
不幸的是,你坚持使用O(n)作为你最快的选择。 除非它们是关于可以利用的时间和删除的时间(例如最大时间跨度)之间的差异的隐藏要求。
正如您所说,您可以开始搜索,其中删除的时间等于(或者首先大于)删除的时间。不幸的是,您需要浏览列表的其余部分,以查看添加的时间是否少于您的时间。
由于比较排序最多为O(n * log(n)),因此无法再次对对象进行排序以提高性能。
有一件事,基于应用程序的启发式方法,按照添加日期的顺序接收数据可能是有益的,但这是在您和您从中获取数据的任何地方之间。
答案 1 :(得分:1)
让我们检查您提供的数据结构:
列表(通常以linked list或dynamic array)或hash map实施。
O(n)
中完成,因此没有任何好处
从数据分类的事实。O(n)
中删除列表中的元素,因此DS不会从中排序。k
元素为O(k)
,无法解决此问题。因此,对于列表排序的相同字段,您甚至无法提高O(n)
到O(logn)
的效果。
某些数据结构(如B+ trees)确实允许有效的范围查询,您可以非常有效地[O(logn)
]从树中删除一系列元素。
但是,它无法帮助您过滤第2个字段的数据,树是未排序的,并根据它进行过滤(除非您可以利用某些相关性) - 仍然需要{{1}时间。
如果您要做的就是稍后迭代新列表,您可以将评估推送到迭代步骤,但不会从中获得任何真正的好处 - 只将处理延迟到何时和如果不需要,则需要并避开它。