在数组大小增加时查找第n个最大数字(多次)

时间:2012-07-09 10:14:27

标签: java algorithm

我们可以使用 O(n)时间复杂度中的 中位数算法 轻松找到第n个。 如果我们必须多次找到同一阵列中第n个最大的数字,那么最好是排序 O(NlogN),然后在 O(1)时间内找到该数字复杂性。
 但是当阵列大小增加时,有效的算法是什么呢? 我们必须找到第n个最大数字,表示array.length /第3个最大或array.length /第2个最大 示例

Array- 1,3,2,4,5 n=2 Answer-4   
New Array 1,3,2,4,5,7  n=2 answer-5  
New Array 1,3,2,4,5,7,3 n=2 answer-5  

注意
n取决于阵列的长度 请帮帮我。

2 个答案:

答案 0 :(得分:7)

我确信你必须始终跟踪整个阵列。假设我们收到100,99,98,...,1,0,-1,......那么第n个最大的数字将遵循相同的顺序,尽管速度减慢:100,100,99,99,98, 98 ...

基本上,我们不能忘记输入中的任何数字,因为在这种情况下,每个数字最终将被选为第n个。

也就是说,每当我们读入一个新元素时,有一个O(log N)算法(对于N,整个元素的数量)“更新”第n个最大元素,这似乎是最佳的。或多或少,只保留n个最大元素的最小优先级队列,以及N-n个较小元素的最大优先级队列。每当n增加(例如,array.length / 3增加)时,将较小元素队列中的内容拉入较大元素队列;每当我们读取一个新元素时,将它放入适当的队列中,可能会将一个元素从“较大元素”队列中撞到“较小元素”队列中。

答案 1 :(得分:0)

有趣的问题。这取决于有多少值是唯一的,以及您开始使用新数组,搜索和插入的频率。

对于许多独特的n,很少从频繁插入/搜索的新阵列开始,我的第一个预感是:

  • 创建最大堆tip和最大堆bulk,让n为您想要的等级(第n个值)
  • 插入:将新节点推送到tip;如果tip.size() >= (n-1),则弹出tip.top()并推送到bulk
  • 搜索:return bulk.top()

这应该为您提供O(N log(N))用于启动,O(log(N))用于插入(比排序快得多)和O(1)用于搜索。

如果唯一值的数量远小于N,我可能会使用计数排序,然后按值对列进行排序。

编辑:更详细地看一下Louis Wasserman的答案,它似乎与我的第一个算法几乎完全重叠。但是,仍然希望建议不要从较小元素队列" 中拉出",而是通过选择max元素作为搜索O(1)。一个进入最小堆。