javaarraysrange-query

How to query a range in an array and print the [xth, x + yth] most frequent integers in the array?


Assume some arbitrary array of ints, for example [3, 1, 1, 1, 13, 13, 13, 13, 13, 8, 8, 8, 8, 8, 8] (order doesnt matter, I just ordered them so its easier to read)

How can I go about creating a method which, when asked for a range, say [2,4], prints the 2nd most, 3rd most, and 4th most frequent integers in the given array? In this example array, it'd print in order of frequencies: Value: 13. Frequency: 5 Value: 1. Frequency: 3 Value: 3. Frequency: 1

noting how the integer 8 is the most frequent integer, and 3 is the 4th most frequent integer.


Solution

  • You want to first fill a map with all integers, where each integer is the key and the frequency is the value. If you encounter an existing integer, you increase the frequency (value).

    You then sort the entries in that map by their values (frequencies) and simply put the result into a list.

    Now you have a sorted list of entrysets where the key is the integer and the value is the frequency, which you can simply access by index:

    public static void main(final String[] args) {
        final int integers[] = new int[] {3, 1, 1, 1, 13, 13, 13, 13, 13, 8, 8, 8, 8, 8, 8};
    
        final Map<Integer, Integer> integerFrequencies = new HashMap<>();
    
        // Create a map of all integers with their frequency:
        for (final int i : integers) {
            if (integerFrequencies.containsKey(i)) {
                integerFrequencies.put(i, integerFrequencies.get(i) + 1);
            }
            else {
                integerFrequencies.put(i, 1);
            }
        }
    
        // Sort the map entries by their value (frequency) into a list:
        final var integerFrequenciesSorted = integerFrequencies.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(Collectors.toList());
    
        // Print 2nd to 4th entry:
        for (int i = 1; i < 4; i++) {
            final var integerFrequency = integerFrequenciesSorted.get(i);
            System.out.println("Value: " + integerFrequency.getKey() + ". Frequency: " +  integerFrequency.getValue());
        }
    }
    

    prints:

    Value: 13. Frequency: 5
    Value: 1. Frequency: 3
    Value: 3. Frequency: 1