LeetCode 3808 - Find Emotionally Consistent Users
This problem asks us to analyze user reactions and determine which users exhibit a strong preference for a particular reaction type. The input is a table named reactions, where each row represents a reaction given by a user to a specific content item.
Difficulty: 🟡 Medium
Topics: —
Solution
LeetCode 3808 - Find Emotionally Consistent Users
Problem Understanding
This problem asks us to analyze user reactions and determine which users exhibit a strong preference for a particular reaction type.
The input is a table named reactions, where each row represents a reaction given by a user to a specific content item. The pair (user_id, content_id) is unique, which means a user can react to a particular piece of content at most once.
For each user, we must first determine how many total reactions they have made. We are only interested in users who have reacted to at least five different content items. Since every row corresponds to a unique content item for that user, this requirement is equivalent to requiring at least five rows for that user.
Next, we need to identify the user's most frequently used reaction. This reaction is called the dominant reaction. We then compute the reaction ratio:
$$\text{reaction_ratio} = \frac{\text{count of dominant reaction}}{\text{total reactions}}$$
A user is considered emotionally consistent if this ratio is at least 0.60.
The output should contain:
user_iddominant_reactionreaction_ratiorounded to two decimal places
The result must be sorted by:
reaction_ratiodescendinguser_idascending
The example illustrates this clearly. User 1 reacted five times, with four "like" reactions. Since 4/5 = 0.80, the user qualifies. User 2's most common reaction appears only twice among five reactions, producing 0.40, which does not qualify. User 3 reacted "love" five times out of five, producing a ratio of 1.00.
An important edge case is users with exactly five reactions. They should still be included if they meet the ratio requirement. Another edge case occurs when multiple reaction types have the same maximum frequency. The problem statement does not specify any tie-breaking rule for the dominant reaction, which means any valid reaction with the maximum frequency is acceptable unless the platform's hidden tests impose additional requirements. Finally, users with fewer than five reactions must always be excluded, regardless of how consistent their reactions are.
Approaches
Brute Force Approach
A straightforward approach would be to process each user independently.
For every user, we could scan all rows belonging to that user and count occurrences of each reaction type. After determining the most frequent reaction, we would compute the ratio and check whether it meets the threshold.
If implemented naively, this might involve repeatedly filtering the table for each user. Suppose there are U users and N total rows. Scanning the entire table for every user would require O(U × N) work.
This approach is correct because it directly computes all required statistics, but it performs unnecessary repeated scans of the same data.
Key Insight
The important observation is that all required information can be computed using aggregation.
For each user we need:
- Total reaction count
- Count of every reaction type
- Maximum reaction count among all reaction types
SQL aggregation naturally provides these values.
We can first group by (user_id, reaction) to count occurrences of each reaction type. Then, for each user, we determine:
- Total reactions
- Maximum reaction frequency
Once we know the maximum frequency and total count, computing the reaction ratio becomes trivial. Finally, we filter users whose total count is at least five and whose ratio is at least 0.60.
Because each row participates in only a small number of aggregate operations, the solution scales efficiently.
Approach Comparison
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(U × N) | O(R) | Repeatedly scans reactions for each user |
| Optimal | O(N) | O(N) | Uses SQL aggregations and grouping |
Here, N is the number of rows in the table and R is the number of distinct reaction types.
Algorithm Walkthrough
- Group the table by
(user_id, reaction)and count how many times each reaction occurs for every user. This gives the frequency of every reaction type. - For each user, compute the total number of reactions. This determines whether the user satisfies the minimum requirement of five reactions.
- For each user, find the maximum reaction frequency among all reaction types. This identifies the dominant reaction count.
- Join the frequency information with the per-user totals and maximum counts.
- Compute the reaction ratio by dividing the dominant reaction count by the total reaction count.
- Keep only users whose total reaction count is at least five.
- Keep only users whose reaction ratio is at least
0.60. - Round the ratio to two decimal places.
- Sort the final result by reaction ratio descending and user ID ascending.
Why it Works
The key invariant is that every user's dominant reaction frequency is exactly the maximum frequency among all reaction types associated with that user. By computing both the total reaction count and this maximum frequency, we obtain the precise ratio required by the problem. Filtering on the total count and ratio thresholds therefore identifies exactly the emotionally consistent users.
Python Solution
LeetCode database problems are solved using SQL rather than Python. A representative SQL solution is shown below.
# This problem is a SQL problem.
# No Python implementation is required on LeetCode.
The LeetCode version of this problem expects a SQL query. The logic described above is implemented using common table expressions that compute reaction frequencies, total counts, and dominant frequencies before applying the required filters.
Go Solution
Similarly, database problems on LeetCode do not require a Go implementation.
// This problem is a SQL problem.
// No Go implementation is required on LeetCode.
Unlike algorithmic problems that operate on arrays or graphs, database problems are executed directly by the SQL engine. Therefore the official submission consists of a SQL query rather than language-specific code.
SQL Solution
WITH reaction_counts AS (
SELECT
user_id,
reaction,
COUNT(*) AS reaction_count
FROM reactions
GROUP BY user_id, reaction
),
user_totals AS (
SELECT
user_id,
COUNT(*) AS total_reactions
FROM reactions
GROUP BY user_id
),
max_reactions AS (
SELECT
user_id,
MAX(reaction_count) AS max_count
FROM reaction_counts
GROUP BY user_id
)
SELECT
rc.user_id,
rc.reaction AS dominant_reaction,
ROUND(
rc.reaction_count * 1.0 / ut.total_reactions,
2
) AS reaction_ratio
FROM reaction_counts rc
JOIN user_totals ut
ON rc.user_id = ut.user_id
JOIN max_reactions mr
ON rc.user_id = mr.user_id
AND rc.reaction_count = mr.max_count
WHERE ut.total_reactions >= 5
AND rc.reaction_count * 1.0 / ut.total_reactions >= 0.60
ORDER BY reaction_ratio DESC, rc.user_id ASC;
The first common table expression computes the frequency of every reaction type for every user. The second computes total reaction counts per user. The third determines the dominant reaction count. The final query combines these results, computes the ratio, applies the required filters, rounds the result, and sorts according to the specification.
Worked Examples
Example 1
Input:
| user_id | content_id | reaction |
|---|---|---|
| 1 | 101 | like |
| 1 | 102 | like |
| 1 | 103 | like |
| 1 | 104 | wow |
| 1 | 105 | like |
Reaction Counts
| user_id | reaction | count |
|---|---|---|
| 1 | like | 4 |
| 1 | wow | 1 |
User Totals
| user_id | total_reactions |
|---|---|
| 1 | 5 |
Maximum Frequency
| user_id | max_count |
|---|---|
| 1 | 4 |
Ratio Calculation
| user_id | dominant_reaction | ratio |
|---|---|---|
| 1 | like | 4/5 = 0.80 |
Since 0.80 ≥ 0.60, the user is included.
Example 2
Input:
| user_id | content_id | reaction |
|---|---|---|
| 2 | 201 | like |
| 2 | 202 | wow |
| 2 | 203 | sad |
| 2 | 204 | like |
| 2 | 205 | wow |
Reaction Counts
| user_id | reaction | count |
|---|---|---|
| 2 | like | 2 |
| 2 | wow | 2 |
| 2 | sad | 1 |
User Totals
| user_id | total_reactions |
|---|---|
| 2 | 5 |
Maximum Frequency
| user_id | max_count |
|---|---|
| 2 | 2 |
Ratio Calculation
| user_id | dominant_reaction | ratio |
|---|---|---|
| 2 | like or wow | 2/5 = 0.40 |
Since 0.40 < 0.60, the user is excluded.
Example 3
Input:
| user_id | content_id | reaction |
|---|---|---|
| 3 | 301 | love |
| 3 | 302 | love |
| 3 | 303 | love |
| 3 | 304 | love |
| 3 | 305 | love |
Reaction Counts
| user_id | reaction | count |
|---|---|---|
| 3 | love | 5 |
User Totals
| user_id | total_reactions |
|---|---|
| 3 | 5 |
Ratio Calculation
| user_id | dominant_reaction | ratio |
|---|---|---|
| 3 | love | 5/5 = 1.00 |
Since 1.00 ≥ 0.60, the user is included.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(N) | Each row participates in a constant number of aggregate operations |
| Space | O(N) | Aggregate tables may store information proportional to grouped rows |
The database performs a small number of grouping operations over the input table. Each reaction row contributes once to the aggregates, resulting in linear processing with respect to the number of rows.
Test Cases
# Conceptual SQL test scenarios
# User qualifies with exactly 60%
# reactions: like, like, like, wow, sad
# ratio = 3/5 = 0.60
# User qualifies with 100%
# reactions: love x 5
# ratio = 1.00
# User does not qualify
# reactions: like, wow, sad, angry, love
# ratio = 1/5 = 0.20
# User has fewer than 5 reactions
# reactions: like x 4
# excluded regardless of ratio
# User has 10 reactions
# dominant reaction appears 6 times
# ratio = 0.60
# qualifies
# User has tie for dominant reaction
# like x 3, wow x 3, sad x 1
# ratio = 3/7 ≈ 0.43
# excluded
Test Summary
| Test | Why |
|---|---|
| Exactly 60% ratio | Verifies inclusive threshold |
| 100% same reaction | Verifies maximum possible ratio |
| No dominant reaction | Verifies rejection logic |
| Fewer than 5 reactions | Verifies minimum activity requirement |
| Large qualifying user | Verifies ratio computation on larger counts |
| Tied dominant reactions | Verifies maximum-frequency handling |
Edge Cases
User Has Exactly Five Reactions
The requirement is "at least five" reactions, not more than five. A common mistake is using a strict greater-than comparison. The solution correctly uses >= 5, ensuring users with exactly five reactions are evaluated.
User Meets the Threshold Exactly
A user whose dominant reaction occurs three times out of five reactions has a ratio of exactly 0.60. The condition is "at least 60%", so these users must be included. The query uses >= 0.60 rather than > 0.60.
Multiple Reactions Tie for Dominance
A user may have two or more reaction types with the same maximum frequency. For example, "like" and "wow" may both appear three times. Since the query joins on the maximum count, multiple rows can be returned for such a user if the ratio threshold is met. If a unique dominant reaction is required, an additional tie-breaking rule such as ROW_NUMBER() would be necessary. Since the problem statement does not specify such a rule, matching all reactions with the maximum frequency is the most faithful interpretation.
User Has Perfect Consistency
When every reaction is identical, the dominant count equals the total count. The ratio becomes exactly 1.00, which should appear at the top of the result due to descending ratio ordering. The solution naturally handles this case through the same formula used for all users.