questions S-W

This commit is contained in:
2025-05-30 19:18:33 +01:00
parent 68699f35ec
commit f7e491f1e8
46 changed files with 9696 additions and 0 deletions

View 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
&nbsp;
**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]`
&nbsp;
**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
&nbsp;
**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.