[英]Efficiently find order statistics of unsorted list prefixes?
A
是以随机顺序从1
到n
的整数数组。
我需要在至少日志时间内随机访问第一个j
元素的第i
个最大元素。
我想出来的,到目前为止是nxn
矩阵M
,其中的元素(i, j)
位置是i
个最大的第一j
。 这给了我恒定的随机访问,但需要n^2
存储。
通过构造, M
按行和列排序。 此外,每列与其邻居的区别在于单个值。
任何人都可以建议一种方法来将M
压缩到n log(n)
空间或更好,具有log(n)
或更好的随机访问时间?
我相信你可以在O(log(N))时间内执行访问,给定O(N log(N))预处理时间和O(N log(N))额外空间。 这是如何做。
您可以扩充红黑树以支持select(i)
操作,该操作在O(log(N))时间内检索排名i
处的元素。 例如, 请参阅此PDF或“ 算法简介”的相应章节。
您可以以功能方式实现红黑树(甚至一个扩充以支持select(i)
),以便插入操作返回一个新树,该树与旧树共享除O(log(N))节点之外的所有节点。 例如,参见Chris Okasaki的Purely Functional Data Structures 。
我们将构建一个纯函数增强红黑树的数组T
,这样树T[j]
存储从最大到最小排序的A
的前j
元素的索引0 ... j-1
。
基本情况:在T[0]
创建一个只有一个节点的增强红黑树,其数据为数字0,它是数组A
的前1个元素中第0个最大元素的索引。
归纳步骤:对于从1到N-1
每个j
,在T[j]
通过纯函数将具有索引j
的新节点插入到树T[j-1]
创建增强的红黑树。 这最多创建了O(log(j))个新节点; 其余节点与T[j-1]
共享。 这需要O(log(j))时间。
构造阵列T
的总时间是O(N log(N)),并且使用的总空间也是O(N log(N))。
一旦创建了T[j-1]
,就可以通过执行T[j-1].select(i)
来访问A
的前j
个元素的第i
个最大元素。 这需要O(log(j))时间。 请注意,您可以在第一次需要时懒惰地创建T[j-1]
。 如果A
非常大且j
总是相对较小,这将节省大量的时间和空间。
除非我误解,否则你只是找到一个数组的第k个顺序统计数据 ,它是另一个数组的前缀。
这可以使用我认为称为“quickselect”的算法或沿着这些行的东西来完成。 基本上,它就像quicksort:
有一个(多)更好的描述在这里 ,如果你搜索的K次快速排序的解决方案下的Quickselect和更快的选择标题,也只是一般在互联网上。
虽然这个算法的最坏情况时间是像快速排序一样的O(n2),但如果你正确选择你的随机枢轴,它的预期情况要好得多(也像快速排序)。 我认为空间复杂度只是O(n); 你可以只制作一个前缀副本来破坏订单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.