1207. Unique Number of Occurrences
Problem Description
In this problem, we are given an array of integers, arr
. Our task is to determine whether the array has the property that no two different numbers appear the same number of times. In other words, each integer's frequency (how often it occurs in the array) should be unique. If this property holds, we return true
, otherwise, we return false
.
For example, suppose the input array is [1, 2, 2, 1, 1, 3]
. Here, the number 1 occurs three times, number 2 occurs twice, and number 3 occurs once. Since all these frequencies (3, 2, 1) are unique, our function would return true
.
However, if we have an array like [1, 2, 2, 3, 3, 3]
, where 1 occurs once, 2 occurs twice, and 3 also occurs three times, we see that the frequencies are not unique. In this case, our function would return false
.
Intuition
To solve this problem, we can follow these steps:
- Count the occurrences of each value in the array.
- Check if the counts are all unique.
The intuition behind the solution lies in the frequency counting mechanic. We can use a data structure that allows us to count the occurrence of each element efficiently. The Python Counter
class from the collections
module is perfect for this job as it creates a dictionary with array elements as keys and their counts as values.
Once we have the counts, we need to check if they are unique. We can convert the counts into a set, which only contains unique elements. If the length of the set of counts (unique frequencies) is equal to the length of the original dictionary of counts, then all frequencies were unique, and we can return true
. Otherwise, we return false
.
Let's illustrate this with our [1, 2, 2, 1, 1, 3] example:
- Step 1:
Counter(arr)
would give us{1: 3, 2: 2, 3: 1}
indicating that 1 appears thrice, 2 appears twice, and 3 appears once. - Step 2: We check with
len(set(cnt.values())) == len(cnt)
which compareslen({3, 2, 1})
tolen({1: 3, 2: 2, 3: 1})
. Since both lengths are 3, they are equal, and the function returnstrue
.
This simple yet efficient approach helps us to determine the uniqueness of each number's occurrences in the given array.
Solution Approach
The solution implementation harnesses the Python collections.Counter
class to count the frequency of each element in the input array arr
. The Counter
class essentially implements a hash table (dictionary) under the hood, which allows efficient frequency counting of hashable objects. Here's a breakdown of the implementation steps according to the provided code:
Step by Step Implementation:
-
The
Counter(arr)
creates a dictionary-like object, where keys are the elements fromarr
, and the values are their respective counts. This step uses a hash table internally to store the counts, offering O(n) time complexity for counting all elements in the array, wheren
is the length of the array.For example, if
arr = [1, 2, 2, 3]
,Counter(arr)
would produceCounter({2: 2, 1: 1, 3: 1})
. -
The expression
set(cnt.values())
takes all the values from the dictionary returned byCounter(arr)
—which are the frequencies of elements—and converts them into a set. Since a set can only contain unique elements, this casting effectively filters out any duplicate counts.Continuing the example above,
set(cnt.values())
converts[2, 1, 1]
to{1, 2}
. -
The comparison
len(set(cnt.values())) == len(cnt)
is checking whether the number of unique frequencies (length of the set) is equal to the number of distinct elements inarr
(length of the Counter dictionary). An equality indicates that all frequencies are unique.In our continuing example,
len({1, 2}) == len(Counter({2: 2, 1: 1, 3: 1}))
reduces to2 == 3
, which isFalse
, reflecting that not all occurrences are unique since 1 and 3 both occur once.
This solution is both elegant and efficient, utilizing the properties of sets and hash tables to check for the uniqueness of the elements' frequencies in the array. There's no need for additional loops or explicit checks for duplicates; the data structures do the heavy lifting. The overall time complexity is O(n), dominated by the counting process. The space complexity is also O(n), as it's necessary to store the counts of elements which, in the worst case, can be as many as the number of elements in the array if all are unique.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example to illustrate the solution approach. Suppose we have the input array arr = [4, 5, 4, 6, 6, 6]
. We want to determine if no two different numbers in the array have the same frequency.
Following the steps outlined in the solution approach:
Step 1: Utilize the Counter
class to count the occurrences of each element in arr
.
We execute cnt = Counter(arr)
and get Counter({4: 2, 6: 3, 5: 1})
. This tells us that the number 4 appears twice, 6 appears three times, and 5 appears once.
Step 2: Convert the counts to a set to check uniqueness.
We convert the values, which are the frequencies, to a set using set(cnt.values())
and obtain {1, 2, 3}
. This set represents the unique frequencies of the numbers in our array.
Step 3: Compare the length of the set of counts to the length of the dictionary of counts to determine if the frequencies are all unique.
We perform the comparison len(set(cnt.values())) == len(cnt)
. The length of our set {1, 2, 3}
is 3
, and the length of our Counter dictionary {4: 2, 6: 3, 5: 1}
is also 3
.
Since 3 == 3
, we can affirm that all counts are unique and therefore return true
for our input array.
The array [4, 5, 4, 6, 6, 6]
confirms our solution's criteria, meaning that no two different numbers in our array appear the same number of times. Hence, our illustrated function returns true
.
Solution Implementation
1from collections import Counter
2from typing import List
3
4class Solution:
5 def uniqueOccurrences(self, arr: List[int]) -> bool:
6 # Create a Counter object that counts occurrences of each element in the array.
7 element_count = Counter(arr)
8
9 # Convert the values of the Counter (which represent the occurrences of each unique element) to a set.
10 # This will remove any duplicate counts.
11 unique_occurrences = set(element_count.values())
12
13 # Check if the number of unique occurrences is equal to the number of unique elements.
14 # If they are equal, it means that no two elements have the same number of occurrences.
15 return len(unique_occurrences) == len(element_count)
16
1class Solution {
2 // This method checks if all elements in the array have unique occurrence counts.
3 public boolean uniqueOccurrences(int[] arr) {
4 // Create a hashmap to store the counts of each number.
5 Map<Integer, Integer> countMap = new HashMap<>();
6
7 // Iterate over the array and populate the countMap.
8 for (int number : arr) {
9 // If the number is already in the map, increment its count, otherwise insert it with count 1.
10 countMap.merge(number, 1, Integer::sum);
11 }
12
13 // Create a hashset containing all the values (occurrence counts) from the countMap.
14 Set<Integer> occurrenceSet = new HashSet<>(countMap.values());
15
16 // If the size of the set (unique occurrences) is the same as the size of the map (unique numbers),
17 // it means that all occurrence counts are unique and we return true. Otherwise, return false.
18 return occurrenceSet.size() == countMap.size();
19 }
20}
21
1#include <vector>
2#include <unordered_map>
3#include <unordered_set>
4using namespace std;
5
6class Solution {
7public:
8 // Function to check if the array has a unique number of occurrences for each element
9 bool uniqueOccurrences(vector<int>& arr) {
10 // Map to store the frequency of each element
11 unordered_map<int, int> frequencyMap;
12
13 // Increment the frequency count for each element in arr
14 for (int element : arr) {
15 ++frequencyMap[element];
16 }
17
18 // Set to store unique occurrence counts
19 unordered_set<int> occurrencesSet;
20
21 // Iterate through the frequency map
22 for (auto& keyValue : frequencyMap) {
23 int occurrence = keyValue.second; // Get the occurrence/frequency count of the element
24
25 // Check if the occurrence count is already in the occurrences set
26 if (occurrencesSet.count(occurrence)) {
27 // If already present, it's not unique and returns false
28 return false;
29 }
30 // If not present, add the occurrence count to the set
31 occurrencesSet.insert(occurrence);
32 }
33
34 // All occurrence counts were unique, return true
35 return true;
36 }
37};
38
1// This function checks if all the elements in the array 'arr' have unique occurrences
2function uniqueOccurrences(arr: number[]): boolean {
3 // Create a Map to count occurrences of each element
4 const occurrenceCount: Map<number, number> = new Map();
5
6 // Iterate over each element in the array
7 for (const num of arr) {
8 // If the element is already in the Map, increment its occurrence count
9 // Otherwise, add the element with an occurrence count of 1
10 occurrenceCount.set(num, (occurrenceCount.get(num) || 0) + 1);
11 }
12
13 // Create a Set from the values of the Map
14 // This will automatically remove any duplicate occurrence counts
15 const uniqueCounts: Set<number> = new Set(occurrenceCount.values());
16
17 // Compare the size of the Set (unique counts) with the size of the Map (all counts)
18 // If they are equal, all occurrence counts are unique
19 return uniqueCounts.size === occurrenceCount.size;
20}
21
Time and Space Complexity
The time complexity of the given code is O(n)
, where n
is the length of the array arr
. This is because counting the occurrences of each element in the array with Counter(arr)
requires a single pass over all elements in arr
, and then converting the counts into a set and comparing the sizes involves operations that are also O(n)
in the worst case.
The space complexity of the code is also O(n)
. The counter object cnt
will store as many entries as there are unique elements in arr
. In the worst case, where all elements are unique, the space required for the counter would be O(n)
. Additionally, when the counts are converted to a set to ensure uniqueness, it occupies another space that could at most be O(n)
, if all counts are unique.
Learn more about how to find time and space complexity quickly using problem constraints.
Which algorithm should you use to find a node that is close to the root of the tree?
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!