Получить индексы n наименьших элементов в массиве

У меня есть int array int[] myArray = new int[100]; и вы хотите получить индексы наименьших 10 (любых n) элементов. Как я могу это сделать?

Ответ 1

создайте объект, который содержит число и индекс, затем создайте массив из этих объектов, затем выполните команду Array.Sort(arrayset [], компаратор) java docs. Затем вы можете просто выбрать верхние элементы x из отсортированного массива.

EDIT: Что-то вроде этого... [Я использовал это для сортировки по "расстоянию"

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;
    }
}

Ответ 2

Сортировка массива, а затем выбор 10 прост, но это будет O (n log n), и если вы не захотите переупорядочить начальный массив, вам также нужно будет сделать копию.

Лучше всего использовать max-heap (или приоритетную очередь), которая автоматически сортирует элементы при их вставке, так что наибольший элемент - это корень node. Пройдите вдоль массива, продолжайте вставлять элементы, пока не нажмете 10; то для каждого последующего элемента просто проверьте, меньше ли он самого большого элемента в куче (постоянная проверка), и если это так, вытащите его и вставьте новый элемент. Когда вы пройдете весь массив, 10 вещей, оставшихся внутри, являются вашими минимальными элементами. Это даст вам результат в O (n log 10) == O (n), поскольку каждая вставка в кучу будет стоить только O (log 10).

Реализация очереди Java Priority Queue по умолчанию является мини-очередью, поэтому вам нужно будет передать в Comparator, который изменит порядок заказов. См. этот вопрос для примера о том, как это сделать. Вам нужно будет создать пользовательский объект, который содержит пары (значение, индекс), если вы хотите получить индексы в конце.

Ответ 3

Прямое решение состоит в том, чтобы перебирать массив и поддерживать список самых маленьких элементов, которые вы нашли, и их индексы. Это решение O (N) и приемлемо в большинстве случаев. Я предполагаю, что это домашняя работа, и у вас должно быть что-то лучше, чем O (N).

Ответ 4

Отсортируйте их по индексу и верните первые 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 ));
        }

    }
}

Ответ 5

Вы можете сортировать массив, зацикливать первые 10 элементов, а затем для каждого поиска элементов в массиве, в котором он имеет... возможно, это не более эффективный способ, но это проще.

Ответ 6

Если вы ищете практический ответ (по сравнению с фактическим сортировкой alg. и т.д.), просто используйте HashMap или PriorityQueue. Если скорость не вызывает беспокойства, попробуйте этот простой alg. Это проще, чем PriorityQueue, поскольку вам не нужен пользовательский объект:

HashMap<Integer, ArrayList<Integer>> indexMap = new HashMap<Integer, ArrayList<Integer>>();

Заполните индексную карту, чтобы мы могли получить индексы для любого заданного числа в массиве

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));
}