我有一个大小为1000的数组。我如何找到五个最大元素的索引(索引)?
下面显示了一个安装代码示例和我的尝试:
Random rand = new Random();
int[] myArray = new int[1000];
int[] maxIndices = new int[5];
int[] maxValues = new int[5];
for (int i = 0; i < myArray.length; i++) {
myArray[i] = rand.nextInt();
}
for (int i = 0; i < 5; i++) {
maxIndices[i] = i;
maxValues[i] = myArray[i];
}
for (int i = 0; i < maxIndices.length; i++) {
for (int j = 0; j < myArray.length; j++) {
if (myArray[j] > maxValues[i]) {
maxIndices[i] = j;
maxValues[i] = myArray[j];
}
}
}
for (int i = 0; i < maxIndices.length; i++) {
System.out.println("Index: " + maxIndices[i]);
}
我知道问题是它总是给所有最大的元素分配最大的最大值。我不确定如何补救这个问题,因为我必须保留myArray
的值和索引。
我不认为排序是一种选择,因为我需要保留索引。事实上,我特别需要的是索引。
8条答案
按热度按时间rjee0c151#
很抱歉回答这个老问题,但我错过了一个具有以下所有属性的实现:
因此,我实现了它:
56lgkhnf2#
排序是一种选择,但需要额外的内存。
所以第4步是(n * lg n),就像排序一样。整个算法是n lg n,代码非常简单。
这里有一个简单的例子,里面可能有bug,很明显,空值检查之类的东西会起作用。
导入java.util数组;
你还可以做一些其他的事情来减少这个操作的开销。例如,你可以选择使用一个只跟踪最大的5的队列,而不是排序。作为
int
s,它们的值可能必须被装箱才能添加到一个集合中(除非你自己滚动),这会显著增加开销。e5nszbig3#
虽然回答得有点晚,但你也可以使用我写的这个函数:
dced5bon4#
我的想法是使用
EvictingQueue
,它最多包含5个元素。你必须用数组中的前五个元素预先填充它(以升序进行,所以你添加的第一个元素是五个元素中最低的)。然后你必须遍历数组,每当当前值大于队列中的最小值时,就向队列中添加一个新元素。为了记住索引,创建一个 Package 对象(一个值/索引对)。
遍历整个数组后,队列中有五个最大值/索引对(按降序排列)。
时间复杂度O(n)
yebdmbv45#
sort(myArray),然后取最后5个元素。
如果要保留原始顺序,请对副本进行排序。
如果你想要索引,没有像python或其他语言那样快速而肮脏的解决方案,你可以排序和扫描,但这很难看。
或者你可以使用objecty --这毕竟是java。创建一个ArrayMaxFilter对象。它将有一个私有类ArrayElement,由一个index和一个value组成,并按值自然排序。它将有一个方法,该方法接受一对int,index和value,创建一个ArrayElement,并将它们放入长度为5的优先级队列中。提交数组中的每个索引/值对,然后报告队列中剩余的值。(是的,优先级队列传统上保留最低值,但您可以在实现中翻转它)
hvvq6cgz6#
下面是我的解决方案。创建一个将indice与value配对的类:
然后在main方法中使用这个类:
以及运行的示例输出:
我提供的示例只生成了10个int,其值在0到99之间,这样我就可以看到它工作了。您可以轻松地更改它以适应任何大小的1000个值。此外,我没有运行3个单独的for循环,而是在向
myArray
添加to之后检查我添加的最新值是否是max值。给予它,看看它是否适合您6rqinv9w7#
我建议使用PriorityQueue,它是一个minmax头,复杂度为O(n log k):
}
你也可以使用Google Guava(也是n log k):
简单地将这些Java实现与Top 10 for 5 Mio条目进行比较,您可以得到:
q9rjltbz8#
简单的O(nlogn)堆解决方案: