A
是一个整数数组,包含从1
到n
的整数,顺序随机。
我需要以至少对数时间访问第一个j
个元素中第i
大的元素。
到目前为止,我想到的是一个n x n
矩阵M
,其中(i, j)
位置上的元素是前j
个元素中第i
大的元素。这样可以在常数时间内进行随机访问,但需要n^2
的存储空间。
按构造方式,M
按行和列排序。此外,每个列与相邻的列仅相差一个值。
有人能建议一种将M
压缩到n log(n)
空间或更小,并具有log(n)
或更好的随机访问时间的方法吗?
A
是一个整数数组,包含从1
到n
的整数,顺序随机。
我需要以至少对数时间访问第一个j
个元素中第i
大的元素。
到目前为止,我想到的是一个n x n
矩阵M
,其中(i, j)
位置上的元素是前j
个元素中第i
大的元素。这样可以在常数时间内进行随机访问,但需要n^2
的存储空间。
按构造方式,M
按行和列排序。此外,每个列与相邻的列仅相差一个值。
有人能建议一种将M
压缩到n log(n)
空间或更小,并具有log(n)
或更好的随机访问时间的方法吗?
select(i)
操作,该操作以 O(log(N)) 的时间检索排名为 i
的元素。例如,可以参考此 PDF 或《算法导论》中的相关章节。select(i)
的增强版本),这样插入操作就会返回一个新树,该树与旧树除了 O(log(N)) 个节点之外完全相同。例如,可以参考 Chris Okasaki 的《纯函数数据结构》。T
,其中存储了纯函数增强红黑树,树 T[j]
存储了按从大到小排序的前 j
个元素的索引 0 ... j-1
。T[0]
创建一个仅有一个节点的增强红黑树,其数据为数字 0,即数组 A
的前 1 个元素中第 0 大元素的索引。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
始终相对较小,则可以节省大量时间和空间。j
单独分配 O(j)
的空间,总共是二次空间。如果你能找到一种将它们合并的方法,那么你就有了一些东西。 - phs