I have an int array int[] myArray = new int[100];
and want to get indexes of smallest 10 (any n) elements. How can I do this?

- 925
- 2
- 9
- 16
-
It would help the community to better help if you showed what you have attempted. Specifically, if you are trying some code and it is not working well, it would be best to show us the snippet that seems to not be working correctly for you. – aperkins May 06 '10 at 20:44
-
@erasmus He is asking if this is for homework or not. Question tagged as homework receive different answers. For instance *How do I sort an array* with `[homework]` tag will lead to an explanation of different sorting algorithms, with out it, will get `Arrays.sort( list );` – OscarRyz May 06 '10 at 20:47
-
@Oscar, I don't think he is sincere. There are some people like him. what they do is decreasing questions's vote values and writing some provocative comments. that guys are just useless things. – erasmus May 06 '10 at 20:54
-
@erasmus: Sometimes the question are posted in an unclear way. I had to read it several times until because I didn't quite get it. I added my answer, see if it's what you need. – OscarRyz May 06 '10 at 21:21
-
@erasmus: I have to agree with Oscar here - the question looked to me to be a homework style question. – aperkins May 06 '10 at 21:30
-
@aperkins: because you've never had to find the smallest x items in an array? :-/ – Kurru May 09 '10 at 14:13
-
@Kurru: no, because in general this is a problem most people who have been in the industry a while know how to solve. This is the type of problem I gave to students in pre-first-year courses to solve. – aperkins May 10 '10 at 14:08
-
@aperkins: whereas all the people who havent been in the industry a while aren't allowed to ask such questions? as a 4th year CS student, I was never given this problem, but have needed to do this type of operation and it didn't occurr to me some of the solutions here. Never mind I self taught when I was 14 with no-one to give me 'problems to solve' – Kurru May 10 '10 at 22:30
-
@Kurru - I was simply responding to the question. That is why I assumed it was that. It was not meant to be insulting, or a statement of one's worth. I was simply saying that the type of question seemed to be more likely school related than not, for the reasons I stated above. All that said, he got some answers to his question. – aperkins May 10 '10 at 23:33
6 Answers
Sorting the array and then picking 10 is simple, but it'd be O(n log n), and if you don't want to re-order the initial array, you'd need to make a copy too.
A better idea is to use a max-heap (or priority queue), which automatically sorts elements as you insert them, such that the largest element is the root node. Walk along the array, keep putting in elements until you hit 10; then, for every subsequent element, simply check if it's smaller than the biggest element in the heap (constant-time check), and if it is, pop that one out and insert the new element. When you've passed through the entire array, the 10 things left inside are your minimum elements. This'll get you your result in O(n log 10) == O(n), since each insert into the heap will only cost O(log 10).
Java's Priority Queue implementation is a min-queue by default, so you'd need to pass in a Comparator that reverses the ordering. See this question for examples on how to do that. You'd need to create a custom object that contains (value, index) pairs too, if you want to get the indices out at the end.
make an object that contains the number and the index, then make an array of these objects, then perform Array.Sort(arrayset[], comparator) java docs. Then you can just pick out the top x items from the sorted array.
EDIT: Something like this... [I had used this to sort according to 'distance'
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;
}
}

- 14,180
- 18
- 64
- 84
Sort them by index and return the first 10
First create the structure to hold both, index and value:
class IndexValue {
final int i;
final int v;
}
Then create an array with this new structure:
IndexValue[] array = new IndexValue[myArray.length];
for( int i = 0 ; i < array.length ; i++ ) {
array[i] = new IndexValue( i, myArray[i] );
}
Finally sort it and take the first N elements
Arrays.sort( array ); // you'll need to implement Comparator though
for( int i = 0 ; i< 10 ;i++ ) {
System.out.print( array[i] );
}
Here's the full working code:
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 ));
}
}
}

- 196,001
- 113
- 385
- 569
The straight forward solution is to iterate over the array and maintain a list of the n smallest elements you've found and their indices. This is an O(N) solution, and acceptable in most cases. I'm guessing though that this is homework and you have to have something better than O(N).

- 20,112
- 2
- 49
- 58
-
1
-
@Kurru, Admittedly the specifics of my answer aren't entirely clear. I think this question was tagged homework before. I don't think it is O(N*M) because one does not have to iterate over the list of M elements. Once the Mth smallest element is found, all subsequent iterations over the list of N merely need to check themselves against the Mth element. I suppose that behavior is best facilitated by using a priority heap. So... O(N*log(M)) ??? – Tim Bender Mar 01 '11 at 21:48
-
So I guess my answer was just a less descriptive version of @tzaman's answer. – Tim Bender Mar 01 '11 at 21:53
-
Does a priority loop have log(M) insert and read in the worst case? Didn't know that – Kurru Mar 02 '11 at 00:27
-
When reading a heap one is usually concerned with the min or max value, implementations usually allow a read complexity of O(1). Insert/delete complexity of O(logN). Here is Java's PriorityQueue: http://download.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html The last line of the javadoc for the class describes the time complexities guaranteed by the current implementation. – Tim Bender Mar 02 '11 at 02:23
You can sort the array, loop the first 10 elements and then for each element search into the array which position it has... maybe it's not the more efficient way, but it's the easier one.

- 198,401
- 62
- 356
- 264
If you are looking for a practical answer (versus the actual sorting alg., etc.), then just use a HashMap or PriorityQueue. If speed isn't a concern try this easy alg. It is easier than a PriorityQueue since you don't need a custom object:
HashMap<Integer, ArrayList<Integer>> indexMap = new HashMap<Integer, ArrayList<Integer>>();
Fill indexMap so we can get the indices for any given number in array
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);
}
For the smallest n numbers in array, print out their index.
Arrays.sort(array);
for (int index = 0; index <= n; index++) {
System.out.println(indexMap.get(array[index]).remove(0));
}

- 2,942
- 2
- 20
- 23