Pick one language and become fluent
You do not need to learn all three for an interview. Choose a language accepted by your target assessment, then practise its collections, sorting, input/output and error handling until you can concentrate on the problem. Use the other implementations here to understand how the same reasoning transfers.
For every exercise, state the input contract and output. Below, count each integer's frequency and return counts in ascending order of integer value. For [3, 1, 3, 2], the counts are 1 → 1, 2 → 1 and 3 → 2. Sorting the output is a requirement, not a property we assume from a hash map.
Python implementation
from collections import Counter
def frequencies(values):
counts = Counter(values)
return sorted(counts.items())
assert frequencies([3, 1, 3, 2]) == [(1, 1), (2, 1), (3, 2)]
assert frequencies([]) == []
assert frequencies([-1, -1, 2]) == [(-1, 2), (2, 1)]
Hash counting takes expected O(n), and sorting k distinct keys takes O(k log k). Memory is O(k). Python integers grow as required, but that does not mean very large integer arithmetic has constant cost. Avoid using a list as a FIFO queue with pop(0): it shifts elements. Use collections.deque for efficient removals from the front.
Java implementation
Save as FrequencyDemo.java. Use an installed JDK, then run javac FrequencyDemo.java and java FrequencyDemo.
import java.util.Map;
import java.util.TreeMap;
public class FrequencyDemo {
static Map<Integer, Integer> frequencies(int[] values) {
Map<Integer, Integer> counts = new TreeMap<>();
for (int value : values) {
counts.merge(value, 1, Integer::sum);
}
return counts;
}
public static void main(String[] args) {
Map<Integer, Integer> result = frequencies(new int[]{3, 1, 3, 2});
if (!result.toString().equals("{1=1, 2=1, 3=2}")) {
throw new AssertionError("Incorrect frequencies");
}
if (!frequencies(new int[]{}).isEmpty()) {
throw new AssertionError("Empty input must stay empty");
}
System.out.println(result);
}
}
TreeMap keeps keys sorted and performs key operations in O(log k), giving O(n log k) time. A HashMap followed by sorting is another valid choice. Explain the trade-off instead of calling every map operation O(1).
Use long when sums can exceed the int range; widening the destination after an overflowing int multiplication is too late. Cast an operand before multiplying. Use .equals() for string content, not ==. For graph traversal, ArrayDeque is a common queue choice. Avoid comparators such as a - b, which can overflow; use Integer.compare(a, b).
C++ implementation
Save as frequency.cpp. With a C++17 compiler, run c++ -std=c++17 frequency.cpp -o frequency and ./frequency.
#include <cassert>
#include <iostream>
#include <map>
#include <vector>
std::map<int, int> frequencies(const std::vector<int>& values) {
std::map<int, int> counts;
for (int value : values) {
++counts[value];
}
return counts;
}
int main() {
auto result = frequencies({3, 1, 3, 2});
assert(result.at(1) == 1);
assert(result.at(2) == 1);
assert(result.at(3) == 2);
assert(frequencies({}).empty());
for (const auto& entry : result) {
std::cout << entry.first << ":" << entry.second << "\n";
}
}
std::map is ordered; std::unordered_map offers expected constant-time operations but does not sort output. counts[value] inserts a default value when the key is absent. For existence checks without insertion, use find.
Know the difference between passing a vector by value and by const reference: copying n elements takes O(n) time and memory. Signed integer overflow is undefined behavior; use an appropriate wider type and reason about bounds. Never index past the vector size. Iterators can be invalidated by modifications such as vector reallocation.
Standard-library fluency checklist
| Need | Python | Java | C++ |
|---|---|---|---|
| Dynamic sequence | list | ArrayList | vector |
| Membership | set | HashSet | unordered_set |
| Key lookup | dict | HashMap | unordered_map |
| FIFO queue | deque | ArrayDeque | queue |
| Priority queue | heapq | PriorityQueue | priority_queue |
| Sort sequence | sorted / list.sort | Arrays.sort / List.sort | std::sort |
The default C++ priority queue is a max-heap; Python's traditional heapq operations and Java's natural-order priority queue are min-heaps. Confirm the ordering you need instead of translating API names mechanically.
Exercises
Implement frequency counting with a hash map and then sort the result. Add a “top k frequent” extension with an explicit tie-break rule. Write tests for empty input, all equal values, negative values and k larger than the number of distinct keys. Explain why the ordered-map and hash-plus-sort implementations have different complexity.
For deeper syntax, use our Python, Java and C/C++ resources. Continue to worked DSA.
References: Python collections, Java collections framework, Microsoft C++ standard library.