TL;DR
Counter, then compare count of frequencies to count of distinct frequencies β O(n) time, O(n) space.
Approach 1 β Brute force
For every distinct value, count its occurrences with a fresh scan; then compare every pair of distinct valuesβ counts.
from typing import List
class Solution:
def uniqueOccurrences(self, arr: List[int]) -> bool:
distinct = []
for x in arr:
if x not in distinct:
distinct.append(x)
counts = [arr.count(x) for x in distinct]
for i in range(len(counts)):
for j in range(i + 1, len(counts)):
if counts[i] == counts[j]:
return False
return True
Complexity: O(nΒ²) time (each arr.count is a full scan, plus the pairwise comparison), O(n) space.
With n <= 1000 this actually passes β the constraints donβt kill it, but it repeats work the hash map does once, and at interview scale (10^5+) it would time out.
Approach 2 β Counter + set of frequencies
The insight: the question βare all frequencies distinct?β is exactly βdoes the list of frequencies contain a duplicate?β, and a set detects duplicates for free β putting the frequencies into a set shrinks it precisely when two values collide on the same count.
collections.Counter is Pythonβs standard hash-map subclass that tallies how many times each element occurs in one pass.
from collections import Counter
from typing import List
class Solution:
def uniqueOccurrences(self, arr: List[int]) -> bool:
freq = Counter(arr)
return len(freq) == len(set(freq.values()))
Walkthrough on arr = [1, 2, 2, 1, 1, 3]:
Counter pass: freq = {1: 3, 2: 2, 3: 1} β three distinct values.
- Frequencies:
[3, 2, 1]; as a set: {3, 2, 1} β still size 3.
3 == 3 β return True.
And on arr = [1, 2]: freq = {1: 1, 2: 1} has 2 entries, but set(freq.values()) is {1} with size 1 β 2 != 1 β False.
Complexity: O(n) time, O(n) space for the counter and the set.
Approach 3 β Sort the frequencies
The insight: duplicates in a sorted list are always adjacent, so instead of a second hash set you can sort the frequency list and look at neighbors. Same answer, different duplicate-detection tool β worth knowing for languages without cheap hash sets.
from collections import Counter
from typing import List
class Solution:
def uniqueOccurrences(self, arr: List[int]) -> bool:
counts = sorted(Counter(arr).values())
return all(a != b for a, b in zip(counts, counts[1:]))
Walkthrough on arr = [1, 2, 2, 1, 1, 3]:
- Frequencies
[3, 2, 1] β sorted [1, 2, 3].
- Adjacent pairs
(1, 2) and (2, 3) are both unequal β True.
Complexity: O(n + k log k) time where k is the number of distinct values, O(n) space.
Common pitfalls
- Deduplicating the values instead of the frequencies β
len(set(arr)) tells you nothing about occurrence counts.
- Comparing
len(set(freq.values())) against len(arr) instead of against len(freq) (the number of distinct values).
- Forgetting that negative values are allowed β an array-indexed count table needs an offset, whereas a hash map does not care.
Pattern takeaway
Hash maps compose: one map answers βhow often does each value occur?β, and feeding its values into a set answers a question about the counts themselves. When a problem asks about a property of frequencies, count first, then treat the frequencies as just another collection to query.