Sort Values by Frequency
Problem
Print each different value with its count as 'value count'. Put the highest count first. If two counts are equal, put the smaller value first.
Constraints
- 1 <= n <= 10^5
Examples
Input
6 3 1 3 2 1 3
Output
3 3 1 2 2 1
Solutions
A map cannot be sorted by value directly. Copy the entries to a list and sort the list with a comparator that has a tie-break rule.
/*
* Problem : Process an array.
* Input : n, then n integers.
* Output : One line per value.
* Approach: Count, then sort the keys.
* Time : O(n log n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String[] solve(int[] a) {
// Step 1: Count each value.
java.util.Map<Integer, Integer> counts = new java.util.HashMap<>();
for (int value : a) {
counts.merge(value, 1, Integer::sum);
}
// Step 2: Put the entries in a list and sort. Higher count first, then smaller value first.
java.util.List<java.util.Map.Entry<Integer, Integer>> entries = new java.util.ArrayList<>(counts.entrySet());
entries.sort((x, y) -> {
if (!x.getValue().equals(y.getValue())) {
return y.getValue() - x.getValue();
}
return Integer.compare(x.getKey(), y.getKey());
});
// Step 3: Make one line for each entry.
String[] output = new String[entries.size()];
for (int i = 0; i < entries.size(); i++) {
output[i] = entries.get(i).getKey() + " " + entries.get(i).getValue();
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = scanner.nextInt();
}
System.out.println(String.join("\n", solve(a)));
}
}
Hints (1)
- What decides the order when two counts are equal?