questions S-W
This commit is contained in:
179
backend/data/questions/unique-number-of-occurrences.yaml
Normal file
179
backend/data/questions/unique-number-of-occurrences.yaml
Normal file
@@ -0,0 +1,179 @@
|
||||
title: Unique Number of Occurrences
|
||||
slug: unique-number-of-occurrences
|
||||
difficulty: easy
|
||||
leetcode_id: 1207
|
||||
leetcode_url: https://leetcode.com/problems/unique-number-of-occurrences/
|
||||
categories:
|
||||
- arrays
|
||||
- hash-tables
|
||||
patterns:
|
||||
- prefix-sum
|
||||
|
||||
description: |
|
||||
Given an array of integers `arr`, return `true` *if the number of occurrences of each value in the array is **unique***, or `false` *otherwise*.
|
||||
|
||||
In other words, no two different values in the array should appear the same number of times.
|
||||
|
||||
constraints: |
|
||||
- `1 <= arr.length <= 1000`
|
||||
- `-1000 <= arr[i] <= 1000`
|
||||
|
||||
examples:
|
||||
- input: "arr = [1,2,2,1,1,3]"
|
||||
output: "true"
|
||||
explanation: "The value 1 has 3 occurrences, 2 has 2 occurrences, and 3 has 1 occurrence. No two values have the same number of occurrences."
|
||||
- input: "arr = [1,2]"
|
||||
output: "false"
|
||||
explanation: "Both 1 and 2 appear exactly once, so their occurrence counts are not unique."
|
||||
- input: "arr = [-3,0,1,-3,1,1,1,-3,10,0]"
|
||||
output: "true"
|
||||
explanation: "The value 1 appears 4 times, -3 appears 3 times, 0 appears 2 times, and 10 appears 1 time. All counts are unique."
|
||||
|
||||
explanation:
|
||||
intuition: |
|
||||
This problem asks us to verify a **uniqueness property about frequencies**, not about the values themselves.
|
||||
|
||||
Think of it like this: imagine you're organising a party and counting how many guests ordered each dish. You want to check if every dish has a *different* number of orders — no two dishes should be equally popular.
|
||||
|
||||
The key insight is that this is a **two-step counting problem**:
|
||||
|
||||
1. First, count how many times each value appears (value → frequency)
|
||||
2. Then, check if all those frequencies are unique (no duplicates in the frequency list)
|
||||
|
||||
A hash map is perfect for the first step (counting), and a set is perfect for the second step (checking uniqueness). Since sets automatically reject duplicates, we can simply compare the number of unique frequencies to the total number of frequencies.
|
||||
|
||||
approach: |
|
||||
We solve this using a **Hash Map + Set Approach**:
|
||||
|
||||
**Step 1: Count occurrences of each value**
|
||||
|
||||
- Create a hash map (dictionary) to store each value and its count
|
||||
- Iterate through the array, incrementing the count for each value
|
||||
- After this step, we have a mapping like `{1: 3, 2: 2, 3: 1}` for the first example
|
||||
|
||||
|
||||
|
||||
**Step 2: Extract the frequency counts**
|
||||
|
||||
- Get all the count values from the hash map
|
||||
- For the first example, this gives us `[3, 2, 1]`
|
||||
|
||||
|
||||
|
||||
**Step 3: Check if all frequencies are unique**
|
||||
|
||||
- Convert the list of frequencies to a set (which removes duplicates)
|
||||
- Compare the size of the set to the size of the original frequency list
|
||||
- If they're equal, all frequencies were unique; if the set is smaller, there were duplicates
|
||||
|
||||
|
||||
|
||||
**Step 4: Return the result**
|
||||
|
||||
- Return `True` if the lengths match, `False` otherwise
|
||||
|
||||
common_pitfalls:
|
||||
- title: Confusing Value Uniqueness with Frequency Uniqueness
|
||||
description: |
|
||||
The problem asks if the **occurrence counts** are unique, not if the values themselves are unique.
|
||||
|
||||
For example, `[1, 2]` has all unique values, but both values appear exactly once. Since the frequencies `[1, 1]` are not unique, the answer is `false`.
|
||||
|
||||
Make sure you're checking uniqueness of the *counts*, not the original array elements.
|
||||
wrong_approach: "Checking if array values are unique"
|
||||
correct_approach: "Counting frequencies, then checking if those frequencies are unique"
|
||||
|
||||
- title: Using a List Instead of a Set
|
||||
description: |
|
||||
Some solutions try to check for duplicate frequencies by iterating through a list and comparing elements. This works but is unnecessarily complex.
|
||||
|
||||
Using a set is the idiomatic way to check for uniqueness — just compare `len(frequencies)` with `len(set(frequencies))`.
|
||||
wrong_approach: "Nested loops to find duplicate frequencies"
|
||||
correct_approach: "Convert to set and compare lengths"
|
||||
|
||||
- title: Forgetting Edge Cases
|
||||
description: |
|
||||
Consider edge cases:
|
||||
- Single element array: `[5]` → frequency is `{5: 1}` → only one count → return `true`
|
||||
- All same elements: `[2, 2, 2]` → frequency is `{2: 3}` → only one count → return `true`
|
||||
|
||||
Both cases have trivially unique frequencies since there's only one distinct value.
|
||||
|
||||
key_takeaways:
|
||||
- "**Two-phase counting pattern**: Many problems require counting elements first, then analysing the counts themselves"
|
||||
- "**Set for uniqueness**: Converting a collection to a set and comparing lengths is the standard way to check for duplicates"
|
||||
- "**Hash map for frequency**: `Counter` or dictionary counting is a fundamental pattern for frequency-based problems"
|
||||
- "**Problem decomposition**: Breaking 'unique occurrences' into 'count frequencies' + 'check uniqueness' makes the solution clear"
|
||||
|
||||
time_complexity: "O(n). We iterate through the array once to count frequencies, then iterate through the frequency values (at most n unique values) to build the set."
|
||||
space_complexity: "O(n). In the worst case, all elements are unique, so the hash map stores n key-value pairs, and the set stores n frequency values."
|
||||
|
||||
solutions:
|
||||
- approach_name: Hash Map and Set
|
||||
is_optimal: true
|
||||
code: |
|
||||
from collections import Counter
|
||||
|
||||
def unique_occurrences(arr: list[int]) -> bool:
|
||||
# Step 1: Count occurrences of each value
|
||||
frequency = Counter(arr)
|
||||
|
||||
# Step 2: Get all the count values
|
||||
counts = frequency.values()
|
||||
|
||||
# Step 3: Check if all counts are unique
|
||||
# If set size equals list size, no duplicates exist
|
||||
return len(counts) == len(set(counts))
|
||||
explanation: |
|
||||
**Time Complexity:** O(n) — One pass to count, one pass to build the set.
|
||||
|
||||
**Space Complexity:** O(n) — Hash map and set each store at most n elements.
|
||||
|
||||
We use Python's `Counter` for concise frequency counting, then leverage the set's uniqueness property. If converting counts to a set reduces the size, there were duplicate frequencies.
|
||||
|
||||
- approach_name: Manual Dictionary Counting
|
||||
is_optimal: true
|
||||
code: |
|
||||
def unique_occurrences(arr: list[int]) -> bool:
|
||||
# Count occurrences using a dictionary
|
||||
frequency = {}
|
||||
for num in arr:
|
||||
# Increment count, defaulting to 0 if not seen
|
||||
frequency[num] = frequency.get(num, 0) + 1
|
||||
|
||||
# Get the frequency counts
|
||||
counts = list(frequency.values())
|
||||
|
||||
# Check uniqueness: set removes duplicates
|
||||
return len(counts) == len(set(counts))
|
||||
explanation: |
|
||||
**Time Complexity:** O(n) — Same as the Counter approach.
|
||||
|
||||
**Space Complexity:** O(n) — Same space usage.
|
||||
|
||||
This approach shows the manual counting logic without relying on `Counter`. It's useful for understanding what happens under the hood or when `Counter` isn't available.
|
||||
|
||||
- approach_name: Sorting Approach
|
||||
is_optimal: false
|
||||
code: |
|
||||
def unique_occurrences(arr: list[int]) -> bool:
|
||||
# Count occurrences
|
||||
frequency = {}
|
||||
for num in arr:
|
||||
frequency[num] = frequency.get(num, 0) + 1
|
||||
|
||||
# Sort the counts
|
||||
counts = sorted(frequency.values())
|
||||
|
||||
# Check adjacent elements for duplicates
|
||||
for i in range(1, len(counts)):
|
||||
if counts[i] == counts[i - 1]:
|
||||
return False
|
||||
|
||||
return True
|
||||
explanation: |
|
||||
**Time Complexity:** O(n log n) — Due to sorting the frequency counts.
|
||||
|
||||
**Space Complexity:** O(n) — Storing frequencies and sorted counts.
|
||||
|
||||
This approach sorts the counts and checks for adjacent duplicates. While correct, sorting adds unnecessary overhead compared to using a set. Included to show an alternative that doesn't use sets.
|
||||
Reference in New Issue
Block a user