Как-то так. Собираем частоты, отбираем элементы с топ тремя частотами.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
final Scanner in = new Scanner(System.in);
final int n = in.nextInt();
final int m = 100;
final int[] freq = new int[m];
for (int i = 0; i < n; i++) {
final int k = in.nextInt();
freq[k-1]++;
}
final int[] maxfk = new int[] { -1, -1, -1 };
for (int k = 0; k < m; k++) {
int f = freq[k];
int c = maxfk[0], j = k;
if (c < 0) {
maxfk[0] = k;
continue;
}
if (f > freq[c]) {
f = freq[c];
j = maxfk[0];
maxfk[0] = k;
}
c = maxfk[1];
if (c < 0) {
maxfk[1] = j;
continue;
}
if (f > freq[c]) {
f = freq[c];
final int t = j;
j = maxfk[1];
maxfk[1] = t;
}
c = maxfk[2];
if (c < 0) {
maxfk[2] = j;
continue;
}
if (f > freq[c]) {
maxfk[2] = j;
}
}
for (int j = 0; j < 3; j++)
if (maxfk[j] >= 0)
System.out.printf("%d - %d\n", maxfk[j] + 1, freq[maxfk[j]]);
}
}
Если во входных данных меньше 3-х различных чисел, то будет выведено, сколько есть (число и его частота в каждой строке, по убыванию частоты). Если с третьей по счёту частотой несколько элементов, то будет выведен наименьший из них. Сами 100 тысяч входных элементов не храним, они являются индексами частот, сдвинутыми на 1.