【问题标题】:Adding the last n element of a sorted set to another将排序集的最后 n 个元素添加到另一个
【发布时间】:2021-07-10 08:01:25
【问题描述】:

我有两个 TreeSet AB。我想以一种有效的方式将B 的最后n 个元素合并到A 中,即。使用排序集的合并。

有没有一种用 Java 实现的有效方法。

我看到的唯一方法是找到n-B的第一个最小元素:b_n,获取tailSet的视图,然后调用A.addAll(B.tailSet(b_n)),但这对我们来说还不够好,因为这将需要在B 中进行额外的n 迭代,并且调用tailSet() 也不是免费的。

最佳方案类似于A.addFromTail(B, n),使用与addAll 相同的合并技术,但在添加n 元素后停止。

【问题讨论】:

  • 使用流来完成工作好吗?

标签: java mergesort treeset


【解决方案1】:

TreeSet 有一个 descendingIterator,它允许你做类似的事情

Iterator<String> iterator = b.descendingIterator();
for (int i = 0; i < n; i++) {
    a.add(iterator.next());
}

另一种方法是使用 Stream API(从 Java 8 开始)和

Iterator<String> iterator = b.descendingIterator();
a.addAll(Stream.generate(iterator::next).limit(Math.min(n, b.size())).collect(Collectors.toList()));

TreeSet.size() 的复杂度为 O(1),因此这可能是轻量级的,您只需遍历 B 的最后 N 个元素。

【讨论】:

  • 计算大小会很轻,但是.stream().skip(all but the last Ns) 会有一些开销。 Stream 将需要发出所有将被丢弃的项目
  • 我想知道 skip(k) 是 O(1) 还是 O(k)。但是当我们收集修剪后的集合时,它必须是 O(k),所以我们并没有真正比找到第 k 个元素然后使用 tailSet 更快。
  • 你是对的。我希望实现来自descendingIterator 的流以使用limit(n) 代替,但是使用标准流API 有点棘手。第一个解决方案可能更好
  • 在 TreeSet 中找到第 n 个元素的时间是 O(n) 而不是 O(log n),总的来说,感觉有点令人失望。
  • TreeSet 的数据结构要求您无法获取索引值。但是根据您的上下文,也许您可​​以使用其他数据结构?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多