Java - Obtain the indexes in ascending order of an int array

Viewed 1361

I have an int array as [2,4,1,0,0,3] and need to obtain from that an array of the indexes in ascending order, means [3,4,2,0,5,1].

I tried to resolve this by using a sorted array to get the numbers in order, then iterating over the original array to find the index when a match happens. As follows:

public class IndexAscendingSorter {
    public static void main (String[] args) {
        int[] array = {2,4,1,0,0,3};
        IndexAscendingSorter finder = new IndexAscendingSorter();
        int[] indixes = finder.orderIndexAscending(array);

        System.out.println("Indexes of the array in ascending order: " +
                            Arrays.toString(indixes));
    }

    public int[] orderIndexAscending(int[] array) {
        int[] minimumIndexes = new int[array.length];
        int[] sortedArray = array.clone();
        Arrays.sort(sortedArray);

        for (int index = 0; index < array.length; index++){
            int minIndex = 0;
            for (int number : array) {
                if (number == sortedArray[index]) { 
                    minimumIndexes[index] = minIndex;
                    break;
                }
                minIndex++;
            }
        }
        return minimumIndexes;
    }
}

The problem is that for same numbers don't return the correct indexes, the output of executing that code is:

Indexes of the array in ascending order: [3, 3, 2, 0, 5, 1] The second value array[1] should have been 4 instead of 3. Does anyone know how can I improve this?

5 Answers

Continuing with your approach, a quick solution would be to use a hash set where you will add the indexes you have already used, and then can check if it is a repeated index. Just change the orderIndexAscending() function to:

    public int[] orderIndexAscending(int[] array) {
        int[] minimumIndexes = new int[array.length];
        int[] sortedArray = array.clone();
        Arrays.sort(sortedArray);
        Set<Integer> savedIndexes = new HashSet<>();

        for (int index = 0; index < array.length; index++){
            int minIndex = 0;
            // Add the index in ascending order, we need to keep the indexes already
            // saved, so won't miss indexes from repeted values
            for (int number : array) {
                if (number == sortedArray[index] && !savedIndexes.contains(minIndex)) { 
                    savedIndexes.add(minIndex);
                    minimumIndexes[index] = minIndex;
                    break;
                }
                minIndex++;
            }
        }
        return minimumIndexes;
    }
}

Pair the numbers with their original indices:

[2,4,1,0,0,3] => [[2,0],[4,1],[1,2],[0,3],[0,4],[3,5]]]

Then sort by the original value:

=> [[0,3],[0,4],[1,2],[2,0],[3,5],[4,1]]]

And lastly extract the indices:

=> [3,4,2,0,5,1]

Initialize the index array to the Integers 0, 1, 2, 3, ..., then sort it, using a custom comperator that looks up the corresponding array values and compares them.

 for (int index = 0; index < array.length; index++){
        int minIndex = 0;
        for (int number : array) {
            if (number == sortedArray[index]) { 
                minimumIndexes[index] = minIndex;
                array[minIndex]=Integer.MAX_VALUE;
                break;
            }
            minIndex++;
        }
    }

You can simply update already visited value with any value never present in the array.

You may simply update the value that has already been visited with any value that is not present in the array.

for (int index = 0; index < array.length; index++){
    int minIndex = 0;
    for (int number : array) {
        if (number == sortedArray[index]) { 
            minimumIndexes[index] = minIndex;
            array[minIndex]=Integer.MAX_VALUE;
            break;
        }
        minIndex++;
    }
}
Related