繁体   English   中英

有效地查找未排序列表前缀的顺序统计信息?

[英]Efficiently find order statistics of unsorted list prefixes?

A是以随机顺序从1n的整数数组。

我需要在至少日志时间内随机访问第一个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:

  1. 随机转动
  2. 交换数组元素,使所有较小的元素都在一侧
  3. 您知道这是第p + 1个最大元素,其中p是较小数组元素的数量
  4. 如果p + 1 = k,那就是解决方案! 如果p + 1> k,则重复'较小'子阵列。 如果p + 1 <k,则在较大的'子阵列'上重复。

有一个(多)更好的描述在这里 ,如果你搜索的K次快速排序的解决方案下的Quickselect和更快的选择标题,也只是一般在互联网上。

虽然这个算法的最坏情况时间是像快速排序一样的O(n2),但如果你正确选择你的随机枢轴,它的预期情况要好得多(也像快速排序)。 我认为空间复杂度只是O(n); 你可以只制作一个前缀副本来破坏订单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM