I was trying to learn Java nowadays, realized that this could be a good exercise. Tried and solved this problem over there in Eclipse. Java is horrible, I went back to C to solve it, here's a solution that I'll explain right after showing it:
#include <stdio.h>
#include <malloc.h>
typedef struct numbergroup {
    int firstencounteridx;
    int count;
    int thenumber;
} Numbergroup;
int firstoneissuperior( Numbergroup gr1, Numbergroup gr2 ) {
    return gr1.count > gr2.count ||   // don't mind the line-break, it's just to fit
    ( gr1.count == gr2.count && gr1.firstencounteridx < gr2.firstencounteridx );
}
void sortgroups( Numbergroup groups[], int amount ) {
    for ( int i = 1; i < amount; i++ ) {
        for ( int j = 0; j < amount - i; j++ ) {
            if ( firstoneissuperior( groups[j + 1], groups[j] ) ) {
                Numbergroup temp = groups[j + 1];
                groups[j + 1] = groups[j];
                groups[j] = temp;
            }
        }
    }
}
int main( ) {
    int input[] = { 2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12 };
    Numbergroup * groups = NULL;
    int amountofgroups = 0;
    for ( int i = 0; i < ( sizeof input / sizeof * input ); i++ ) {
        int uniqueencounter = 1;
        for ( int j = 0; j < amountofgroups; j++ ) {
            if ( groups[j].thenumber == input[i] ) {
                uniqueencounter = 0;
                groups[j].count++;
                break;
            }
        }
        if ( uniqueencounter ) {
            groups = realloc( groups, ( amountofgroups + 1 ) * sizeof * groups );
            groups[amountofgroups].firstencounteridx = i;
            groups[amountofgroups].count = 1;
            groups[amountofgroups].thenumber = input[i];
            amountofgroups++;
        }
    }
    sortgroups( groups, amountofgroups );
    for ( int i = 0; i < amountofgroups; i++ )
        for ( int j = 0; j < groups[i].count; j++ )
            printf( "%d ", groups[i].thenumber );
    free( groups );
    putchar( 10 );
    return 0;
}
Let me explain the structure first, as well as its functionality: It is for each unique number. In your example, it is for 2s, 3s, 4s, 5s and the 12s, one for each, 5 in total. Each one is to store:
- the index of the first encounter of that number
- the amount of encounter of that number
- the value of that number
For example, for 12s, it shall store:
- firstencounteridxas- 5, that is the index of the first 12
- countas- 2
- thenumberas- 12
The first loop generally does that. It expands the group of Numbergroups whenever a unique number is encountered, stores its index as well; increases the count in case a number that already has a group has been encountered.
Then a sort is issued, which simply is a bubble sort. Might be different than the conventional one, I don't have any memorized.
Sorting criteria function simply checks if the count field of the first group is greater than the other; otherwise it checks whether they are the same and the firstencounter of the first group is earlier than the other; in which cases it returns 1 as true. Those are the only possible ways for the first group to be considered superior than the second one.
That's one method, there can be others. This is just a suggestion, I hope it helps you, not just for this case, but in general.