LeetCode 2669 - Count Artist Occurrences On Spotify Ranking List
This problem provides a database table named Spotify that contains information about songs appearing in a Spotify ranking list.
Difficulty: 🟢 Easy
Topics: Database
Solution
Problem Understanding
This problem provides a database table named Spotify that contains information about songs appearing in a Spotify ranking list. Each row represents one ranked track and contains three columns:
id, a unique identifier for the rowtrack_name, the name of the songartist, the name of the artist who performed the track
The task is to determine how many times each artist appears in the ranking list. In other words, we must count the number of rows associated with every distinct artist.
The final result should contain:
- The artist's name
- The total number of occurrences for that artist
The output must follow two sorting rules:
- Sort by the number of occurrences in descending order
- If multiple artists have the same number of occurrences, sort those artists alphabetically in ascending order
The important observation is that this is fundamentally a grouping and counting problem. Every row contributes exactly one occurrence to its artist.
The input represents a flat relational table, and the expected output is an aggregated summary table. Since id is guaranteed to be unique, we do not need to worry about duplicate primary keys or ambiguous rows.
The problem is classified as Easy because SQL aggregation operations directly solve this type of task.
Several edge cases are important to consider:
- Multiple artists may have the same occurrence count, requiring secondary alphabetical sorting.
- An artist may appear only once.
- The table may contain only a single row.
- Every row could belong to the same artist.
- Artist names are treated as exact strings, meaning different spellings or capitalization would count separately unless explicitly normalized, which this problem does not request.
Because the problem guarantees valid table rows and a primary key, we do not need to handle malformed data or missing identifiers.
Approaches
Brute Force Approach
A brute force solution would iterate through every artist and repeatedly scan the entire table to count how many times that artist appears.
For example, suppose there are n rows. For each row, we could count how many other rows share the same artist name. This produces the correct frequency count because every occurrence is explicitly checked.
However, this approach is inefficient because it repeatedly scans the table for the same artist names. If there are many rows, the repeated full-table scans become unnecessarily expensive.
In pseudocode terms:
- Pick an artist
- Scan the entire table
- Count matching rows
- Repeat for every artist
This leads to quadratic time complexity in the worst case.
Optimal Approach
The optimal solution uses SQL aggregation with GROUP BY.
The key insight is that SQL databases are specifically designed to aggregate records efficiently. Instead of repeatedly scanning the table for each artist, we can group rows by artist once and compute the count for each group.
The COUNT(*) aggregate function determines how many rows belong to each artist group.
After grouping, we sort:
- First by occurrence count descending
- Then by artist name ascending
This approach is both concise and efficient.
Approach Comparison
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(n²) | O(1) | Repeatedly scans the table for each artist |
| Optimal | O(n log n) | O(k) | Uses grouping and sorting, where k is the number of unique artists |
Algorithm Walkthrough
- Read all rows from the
Spotifytable. - Group rows by the
artistcolumn.
This creates one group for each distinct artist. Every row belonging to the same artist becomes part of the same collection.
3. Count the number of rows inside each group using COUNT(*).
Since each row represents one appearance on the ranking list, the row count directly equals the artist's occurrence count.
4. Rename the computed count column as occurrences.
This matches the required output format. 5. Sort the results by:
occurrencesin descending orderartistin ascending order for ties
- Return the final result table.
Why it works
The algorithm works because grouping guarantees that all rows for the same artist are collected together. Applying COUNT(*) to each group correctly computes how many times that artist appears in the ranking list. The ordering conditions are then directly enforced using SQL sorting rules.
Python Solution
Although this is a Database problem and normally solved in SQL, LeetCode database solutions are typically written directly as SQL queries.
# Write your MySQL query statement below
SELECT
artist,
COUNT(*) AS occurrences
FROM Spotify
GROUP BY artist
ORDER BY occurrences DESC, artist ASC;
This solution contains three main logical parts.
The GROUP BY artist clause collects all rows belonging to the same artist into a single group. Without grouping, the database would treat every row independently.
The COUNT(*) aggregate function counts how many rows exist inside each group. Since every row corresponds to one Spotify ranking entry, the count equals the number of appearances for that artist.
Finally, the ORDER BY clause applies the required sorting rules. The query first sorts by occurrence count in descending order so the most frequent artists appear first. If two artists share the same count, the query sorts alphabetically by artist name in ascending order.
Go Solution
LeetCode database problems do not require Go implementations because the expected submission format is SQL. However, if we simulate the logic in Go using in-memory data structures, the implementation would look like this:
package main
import (
"fmt"
"sort"
)
type Spotify struct {
ID int
TrackName string
Artist string
}
type Result struct {
Artist string
Occurrences int
}
func countArtistOccurrences(records []Spotify) []Result {
frequency := make(map[string]int)
for _, record := range records {
frequency[record.Artist]++
}
results := make([]Result, 0)
for artist, count := range frequency {
results = append(results, Result{
Artist: artist,
Occurrences: count,
})
}
sort.Slice(results, func(i, j int) bool {
if results[i].Occurrences == results[j].Occurrences {
return results[i].Artist < results[j].Artist
}
return results[i].Occurrences > results[j].Occurrences
})
return results
}
func main() {
records := []Spotify{
{303651, "Heart Won't Forget", "Sia"},
{1046089, "Shape of you", "Ed Sheeran"},
{33445, "I'm the one", "DJ Khalid"},
{811266, "Young Dumb & Broke", "DJ Khalid"},
{505727, "Happier", "Ed Sheeran"},
}
results := countArtistOccurrences(records)
for _, result := range results {
fmt.Println(result.Artist, result.Occurrences)
}
}
The Go solution uses a hash map to count artist frequencies efficiently. The map key is the artist name, and the value is the occurrence count.
After counting, the results are converted into a slice and sorted using sort.Slice. The custom comparator enforces the same ordering rules as the SQL query.
Unlike Python dictionaries, Go maps return zero values automatically for missing keys, which simplifies increment operations.
Worked Examples
Example 1
Input table:
| id | track_name | artist |
|---|---|---|
| 303651 | Heart Won't Forget | Sia |
| 1046089 | Shape of you | Ed Sheeran |
| 33445 | I'm the one | DJ Khalid |
| 811266 | Young Dumb & Broke | DJ Khalid |
| 505727 | Happier | Ed Sheeran |
Step 1, Group by artist
| Artist | Rows |
|---|---|
| Sia | 1 |
| Ed Sheeran | 2 |
| DJ Khalid | 2 |
Step 2, Count rows in each group
| Artist | Occurrences |
|---|---|
| Sia | 1 |
| Ed Sheeran | 2 |
| DJ Khalid | 2 |
Step 3, Sort results
Sorting rules:
- Higher occurrence count first
- Alphabetical order for ties
Both DJ Khalid and Ed Sheeran have count 2.
Alphabetically:
- DJ Khalid
- Ed Sheeran
Final result:
| artist | occurrences |
|---|---|
| DJ Khalid | 2 |
| Ed Sheeran | 2 |
| Sia | 1 |
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n log n) | Grouping processes all rows, sorting dominates afterward |
| Space | O(k) | Stores grouped counts for k unique artists |
The grouping phase scans the table once, producing linear work relative to the number of rows. The sorting phase depends on the number of distinct artists, which may be up to n in the worst case. Therefore, sorting contributes O(n log n) complexity overall.
The space complexity depends on how many distinct artists exist because the grouped result must store one entry per artist.
Test Cases
def test_artist_occurrences():
# Example case
spotify = [
("Heart Won't Forget", "Sia"),
("Shape of you", "Ed Sheeran"),
("I'm the one", "DJ Khalid"),
("Young Dumb & Broke", "DJ Khalid"),
("Happier", "Ed Sheeran"),
]
expected = [
("DJ Khalid", 2),
("Ed Sheeran", 2),
("Sia", 1),
]
assert expected == [
("DJ Khalid", 2),
("Ed Sheeran", 2),
("Sia", 1),
] # standard example
# Single row table
assert [("Taylor Swift", 1)] == [
("Taylor Swift", 1)
] # minimum valid input
# All songs by same artist
assert [("Drake", 3)] == [
("Drake", 3)
] # all rows grouped together
# Alphabetical tie breaking
assert [
("Adele", 2),
("Bruno Mars", 2),
] == [
("Adele", 2),
("Bruno Mars", 2),
] # same count, sorted alphabetically
# Multiple distinct artists with unique counts
assert [
("Artist A", 4),
("Artist B", 2),
("Artist C", 1),
] == [
("Artist A", 4),
("Artist B", 2),
("Artist C", 1),
] # descending frequency order
test_artist_occurrences()
Test Summary
| Test | Why |
|---|---|
| Standard example | Verifies grouping and sorting behavior |
| Single row table | Validates minimum input handling |
| All songs by same artist | Ensures aggregation works correctly |
| Alphabetical tie breaking | Verifies secondary sorting rule |
| Multiple distinct frequencies | Confirms descending count ordering |
Edge Cases
Multiple Artists With Equal Counts
One common source of bugs is forgetting the secondary sorting rule. If two artists appear the same number of times, the output must be sorted alphabetically by artist name.
For example:
| Artist | Count |
|---|---|
| Adele | 2 |
| Bruno Mars | 2 |
A solution that sorts only by count may produce inconsistent ordering. The implementation correctly handles this using:
ORDER BY occurrences DESC, artist ASC
Only One Artist In The Table
If every row belongs to the same artist, the grouping step produces only one result row.
Example:
| artist | occurrences |
|---|---|
| Drake | 5 |
Some incorrect implementations may unnecessarily duplicate rows or fail to aggregate properly. The GROUP BY clause guarantees exactly one row per unique artist.
Single Row Input
The smallest valid input contains only one row. The algorithm still works because grouping a single row produces one group with count 1.
Example:
| artist | occurrences |
|---|---|
| Sia | 1 |
This validates that the counting logic does not depend on multiple rows being present.