Java 获取数组中n个最小元素的索引
我有一个int数组int[]myArray=newint[100];并希望得到任意n个元素中最小的10个元素的索引。如何执行此操作?创建一个包含数字和索引的对象,然后创建这些对象的数组,然后执行array.Sortarrayset[],comparator。然后,您可以从排序后的数组中挑出前x个项目 编辑: 像这样的。。。[我用它来按“距离”排序Java 获取数组中n个最小元素的索引,java,Java,我有一个int数组int[]myArray=newint[100];并希望得到任意n个元素中最小的10个元素的索引。如何执行此操作?创建一个包含数字和索引的对象,然后创建这些对象的数组,然后执行array.Sortarrayset[],comparator。然后,您可以从排序后的数组中挑出前x个项目 编辑: 像这样的。。。[我用它来按“距离”排序 import java.util.Arrays; import java.util.Comparator; public class Nearest
import java.util.Arrays;
import java.util.Comparator;
public class NearestObject
{
public NearestObject(int position, int distance)
{
this.Position = position;
this.Distance = distance;
}
public int Position = 0;
public int Distance = 0;
public static NearestObject[] SortDistance(NearestObject[] items)
{
Arrays.sort(items, new DistanceSort());
return items;
}
}
class DistanceSort implements Comparator<NearestObject>
{
public int compare(NearestObject o1, NearestObject o2)
{
return o1.Distance - o2.Distance;
}
}
对数组进行排序,然后选择10是很简单的,但它会在日志n上,如果不想对初始数组重新排序,也需要制作一个副本 更好的方法是使用最大堆或优先级队列,它在插入元素时自动对元素进行排序,这样最大的元素就是根节点。沿着数组走,一直放入元素,直到达到10;然后,对于后续的每个元素,只需检查它是否小于堆常量时间检查中的最大元素,即如果是nd,则弹出该元素并插入新元素。当您遍历整个数组时,剩下的10个元素是您的最小元素。这将使您在日志10==On中得到结果,因为每次插入堆只需要花费Olog 10
默认情况下,Java的优先级队列实现是一个最小队列,因此您需要传入一个反向排序的比较器。有关如何做到这一点的示例,请参阅。如果您想在最后得到索引,您需要创建一个包含值、索引对的自定义对象。您可以对数组排序,循环前10个元素然后对每个元素搜索它所在的数组…也许这不是更有效的方法,但更简单。按索引对它们排序并返回前10个 首先,创建同时包含索引和值的结构:
class IndexValue {
final int i;
final int v;
}
然后使用此新结构创建一个数组:
IndexValue[] array = new IndexValue[myArray.length];
for( int i = 0 ; i < array.length ; i++ ) {
array[i] = new IndexValue( i, myArray[i] );
}
最后对其进行排序,并获取前N个元素
Arrays.sort( array ); // you'll need to implement Comparator though
for( int i = 0 ; i< 10 ;i++ ) {
System.out.print( array[i] );
}
以下是完整的工作代码:
import java.util.Arrays;
import java.util.Random;
import java.util.Comparator;
import static java.lang.System.out;
class IndexValue {
final int i,v;
public IndexValue( int i, int v ) {
this.i = i;
this.v = v;
}
}
public class SortByIndex {
public static void main( String [] args ) {
Random random = new Random();
int [] myArray = new int[100];
IndexValue[] array = new IndexValue[myArray.length];
// Fill the array
for( int i = 0 ; i < 100; i++ ) {
myArray[i] = random.nextInt();
array[i] = new IndexValue( i, myArray[i] );
}
// Sort it
Arrays.sort( array, new Comparator<IndexValue>(){
public int compare( IndexValue a, IndexValue b ){
return a.v - b.v;
}
});
// Print it
out.println("Top:");
for( int i = 0 ; i < 10 ; i++ ) {
out.println( String.format("array[%d]=%d", array[i].i, array[i].v ));
}
}
}
直截了当的解决方案是迭代数组,并维护一个包含已找到的n个最小元素及其索引的列表。这是一个ON解决方案,在大多数情况下都是可以接受的。我猜这是一个家庭作业,你必须有比ON更好的解决方案。如果你想寻找一个实际答案,而不是实际答案排序alg.,等等,然后只使用HashMap或PriorityQueue。如果速度不是问题,请尝试此简单alg。它比PriorityQueue更容易,因为您不需要自定义对象: HashMap indexMap=新的HashMap 填充indexMap,这样我们就可以得到数组中任意给定数字的索引
for (int index = 0; index <= array.size; index++) {
if (indexMap.get(array[index]) == null) { // Prime it with an ArrayList
indexMap.put(array[index], new ArrayList<Integer>());
}
indexMap.get(array[index]).add(index);
}
对于数组中最小的n个数字,打印出它们的索引
Arrays.sort(array);
for (int index = 0; index <= n; index++) {
System.out.println(indexMap.get(array[index]).remove(0));
}
如果你展示了你所做的尝试,将有助于社区更好地提供帮助。特别是,如果你正在尝试一些代码,但效果不好,最好向我们展示似乎不适合你的代码片段。@erasmus他问这是否是家庭作业。标记为家庭作业的问题会得到不同的答案。例如,如何使用[作业]对数组进行排序tag将导致对不同排序算法的解释,没有它,将得到Arrays.sort list;@Oscar,我不认为他是真诚的。有一些人喜欢他。他们做的是减少问题的投票值,并写一些挑衅性的评论。这些人只是无用的东西。@erasmus:有时问题会被张贴在不清楚的方式。我不得不读了好几遍,直到我没有完全理解。我添加了我的答案,看看它是否是你需要的。@伊拉斯谟:我必须同意奥斯卡的观点-在我看来,这个问题是一个家庭作业式的问题。不是在*m?n=输入大小,m=数字上吗items@Kurru诚然,我的回答的细节并不完全清楚。我认为不是他的问题以前被标记为家庭作业。我不认为是ONM,因为人们不必迭代M个元素的列表。一旦找到第M个最小的元素,N个元素列表上的所有后续迭代只需要对照第M个元素进行检查。我认为,使用优先级堆最有利于行为。因此。。。ONlogM???所以我猜我的答案只是@tzaman答案的一个不太具描述性的版本。优先级循环在最坏的情况下是否具有logM insert和read?我不知道在读取堆时,通常与最小值或最大值有关,实现通常允许O1的读取复杂性。OlogN的插入/删除复杂性。以下是Java的PriorityQueue:类的javadoc的最后一行描述了当前实现所保证的时间复杂性。