5

Hi I want to get the lowest 3 elements of an array. By lowest I mean the minimum value. I cannot use the collections.Sort method as I need to know the index of the elements. Therefore I am using the following code to get the lowest, but I need to know how I can get the lowest 3.

int minimum = grades[1];
int index = 1;

for(i=1; i<= numberOfStudents; i++){
    if (grades[i]<minimum){
        minimum = grades[i];
        index = i;
    }
}
Sujay
  • 6,753
  • 2
  • 30
  • 49
M9A
  • 3,168
  • 14
  • 51
  • 79
  • 5
    Why are you starting your array indexes at 1? – Clark Dec 02 '12 at 22:25
  • There might be a better way, but I would just sort it by the value you want to and then just grab the first 3 of the sorted array. – Throttlehead Dec 02 '12 at 22:25
  • @Jacob he specifically said he can't use that. – tckmn Dec 02 '12 at 22:26
  • 1
    Just copy the array and sort the copy. Or keep track of 3 elements instead of 1 when looping through. Basic programming :p – keyser Dec 02 '12 at 22:26
  • @Clark - Because the first element is not relevant to what I need to achieve – M9A Dec 02 '12 at 22:33
  • @Keyser - How would I be able to keep track of 3 elements? – M9A Dec 02 '12 at 22:34
  • The top voted answer below has one way. I myself wouldn't have used an array though. The idea is the same as it is with 1 element, but you try to fit new values into any of the three (lowest, second-lowest,third-lowest). – keyser Dec 02 '12 at 22:37
  • Java can be verbose in cases like this. In Scala for example this could be solved with a single line of code. val lowestThreeIndices = grades.zipWithIndex.sorted.take(3).map(_._2) – Tesseract Dec 02 '12 at 22:49

5 Answers5

4

Here is a really simple way of doing it:

public static void main(String[] args) {
    int[] myArray = { 5, 8, 12, 9, 50, 11, 4 };

    System.out.println(Arrays.toString(myArray));
    System.out.println(Arrays.toString(getThreeLowest(myArray)));
}

private static int[] getThreeLowest(int[] array) {
    int[] lowestValues = new int[3];
    Arrays.fill(lowestValues, Integer.MAX_VALUE);

    for(int n : array) {
        if(n < lowestValues[2]) {
            lowestValues[2] = n;
            Arrays.sort(lowestValues);
        }
    }
    return lowestValues;
}

This outputs:

[5, 8, 12, 9, 50, 11, 4]
[4, 5, 8]


The call to Arrays.sort is only done to the local array, not your main array. The reason it does this is just to simplify the comparison against n.

Phil K
  • 4,939
  • 6
  • 31
  • 56
  • I need to know the indexes of the lowest 3 though – M9A Dec 02 '12 at 22:35
  • You could do exactly what he types, but instead of storing the values in the lowestValues array, store the index (you'd have to use a loop instead of a foreach), then add a comparator to the sort call that compares the values from the indexes stored in the lowestValues. – billjamesdev Dec 02 '12 at 22:49
3

Building off what you had

    int[] grades = { 100, 99, 98, 97, 10, 95, 11, 9, 94 };
    int numberOfStudents = grades.length;

    int minimum = grades[1];
    int minimum2 = grades[1];
    int minimum3 = grades[1];
    int index = 1;
    int index2 = 1;
    int index3 = 1;

    for(int i=1; i< numberOfStudents; i++){
        if (grades[i]<minimum3 && grades[i]>=minimum2){
            minimum3 = grades[i];
            index3 = i;
        }
        if (grades[i]<minimum2 && grades[i]>=minimum){
            //We have a new 2nd lowest - shift previous 2nd lowest up
            minimum3 = minimum2;
            index3 = index2;
            minimum2 = grades[i];
            index2 = i;
        }
        if (grades[i]<minimum){
            //We have a new lowest - shift previous lowest up
            minimum3 = minimum2;
            index3 = index2;
            minimum2 = minimum;
            index2 = index;
            minimum = grades[i];
            index = i;
        }
    }
    System.out.println("Smallest is at " + index + " with value of " + minimum);
    System.out.println("Next Smallest is at " + index2 + " with value of " + minimum2);
    System.out.println("Next Smallest is at " + index3 + " with value of " + minimum3);
Tad
  • 934
  • 6
  • 10
1

This may be a bit 'too much' but off the top of my head possible that you could make an array of objects, each object containing the value and index it has in the original 'grades' array and sort that?

The only other way I can think of is to good through the array and manually keep track of the 3 lowest elements and their indexes like what you're already doing...

mitim
  • 3,169
  • 5
  • 21
  • 25
0

Take three variables: the smallest, second smallest and third smallest. In the same way you are finding your smallest element, find at each step which are the three smallest elements.

You need to check if any element is smaller than the smallest number, or it is between the smallest and the second smallest, or it is between the second smallest and the third smallest.

As this is probably an assignment, task or homework, i will not write the code here.

andreih
  • 423
  • 1
  • 6
  • 19
0

Can we do

    int[] myArray = { 5, 8, 12, 9, 50, 11, 4 };
    Arrays.sort(myArray);
    System.out.println(myArray[0] +","+ myArray[1] +","+ myArray[2]);
Kiran
  • 1