Find Books with Polarized Opinions solution and explanation
4 more videos on this problem
Leetcode 3642 - Using SUM to COUNT in SQL - Books with Polarized Opinions | Everyday Data ScienceEveryday Data Science · 12:22 · 474 views
Leetcode 3642 Find Books with Polarized OpinionsAlgorithmicIQ · 14:50 · 68 views
LeetCode SQL Problem - Find Books with Polarized Opinions #leetcode #sqlRanvir Singh Matharu · 0:12 · 5 views
LeetCode, SQL, 3642. Find Books with Polarized Opinions, MediumДиванная аналитика · 32:10 · 3 views
LeetCode, Pandas,, 3642. Find Books with Polarized Opinions, MediumДиванная аналитика · 18:18 · 1 view
The problem
Table: books
+-------------+---------+ | Column Name | Type | +-------------+---------+ | book_id | int | | title | varchar | | author | varchar | | genre | varchar | | pages | int | +-------------+---------+ book_id is the unique ID for this table. Each row contains information about a book including its genre and page count.
Table: reading_sessions
+----------------+---------+ | Column Name | Type | +----------------+---------+ | session_id | int | | book_id | int | | reader_name | varchar | | pages_read | int | | session_rating | int | +----------------+---------+ session_id is the unique ID for this table. Each row represents a reading session where someone read a portion of a book. session_rating is on a scale of 1-5.
Write a solution to find books that have polarized opinions - books that receive both very high ratings and very low ratings from different readers.
- A book has polarized opinions if it has
at least one rating ≥ 4andat least one rating ≤ 2 - Only consider books that have at least
5reading sessions - Calculate the rating spread as (
highest_rating - lowest_rating) - Calculate the polarization score as the number of extreme ratings (
ratings ≤ 2 or ≥ 4) divided by total sessions - Only include books where
polarization score ≥ 0.6(at least60%extreme ratings)
Return the result table ordered by polarization score in descending order, then by title in descending order.
The polarization score should be rounded to 2 decimal places.
The result format is in the following example.
Example:
Input:
books table:
+---------+------------------------+---------------+----------+-------+ | book_id | title | author | genre | pages | +---------+------------------------+---------------+----------+-------+ | 1 | The Great Gatsby | F. Scott | Fiction | 180 | | 2 | To Kill a Mockingbird | Harper Lee | Fiction | 281 | | 3 | 1984 | George Orwell | Dystopian| 328 | | 4 | Pride and Prejudice | Jane Austen | Romance | 432 | | 5 | The Catcher in the Rye | J.D. Salinger | Fiction | 277 | +---------+------------------------+---------------+----------+-------+
reading_sessions table:
+------------+---------+-------------+------------+----------------+ | session_id | book_id | reader_name | pages_read | session_rating | +------------+---------+-------------+------------+----------------+ | 1 | 1 | Alice | 50 | 5 | | 2 | 1 | Bob | 60 | 1 | | 3 | 1 | Carol | 40 | 4 | | 4 | 1 | David | 30 | 2 | | 5 | 1 | Emma | 45 | 5 | | 6 | 2 | Frank | 80 | 4 | | 7 | 2 | Grace | 70 | 4 | | 8 | 2 | Henry | 90 | 5 | | 9 | 2 | Ivy | 60 | 4 | | 10 | 2 | Jack | 75 | 4 | | 11 | 3 | Kate | 100 | 2 | | 12 | 3 | Liam | 120 | 1 | | 13 | 3 | Mia | 80 | 2 | | 14 | 3 | Noah | 90 | 1 | | 15 | 3 | Olivia | 110 | 4 | | 16 | 3 | Paul | 95 | 5 | | 17 | 4 | Quinn | 150 | 3 | | 18 | 4 | Ruby | 140 | 3 | | 19 | 5 | Sam | 80 | 1 | | 20 | 5 | Tara | 70 | 2 | +------------+---------+-------------+------------+----------------+
Output:
+---------+------------------+---------------+-----------+-------+---------------+--------------------+ | book_id | title | author | genre | pages | rating_spread | polarization_score | +---------+------------------+---------------+-----------+-------+---------------+--------------------+ | 1 | The Great Gatsby | F. Scott | Fiction | 180 | 4 | 1.00 | | 3 | 1984 | George Orwell | Dystopian | 328 | 4 | 1.00 | +---------+------------------+---------------+-----------+-------+---------------+--------------------+
Explanation:
- The Great Gatsby (book_id = 1):
- Has 5 reading sessions (meets minimum requirement)
- Ratings: 5, 1, 4, 2, 5
- Has ratings ≥ 4: 5, 4, 5 (3 sessions)
- Has ratings ≤ 2: 1, 2 (2 sessions)
- Rating spread: 5 - 1 = 4
- Extreme ratings (≤2 or ≥4): All 5 sessions (5, 1, 4, 2, 5)
- Polarization score: 5/5 = 1.00 (≥ 0.6, qualifies)
- 1984 (book_id = 3):
- Has 6 reading sessions (meets minimum requirement)
- Ratings: 2, 1, 2, 1, 4, 5
- Has ratings ≥ 4: 4, 5 (2 sessions)
- Has ratings ≤ 2: 2, 1, 2, 1 (4 sessions)
- Rating spread: 5 - 1 = 4
- Extreme ratings (≤2 or ≥4): All 6 sessions (2, 1, 2, 1, 4, 5)
- Polarization score: 6/6 = 1.00 (≥ 0.6, qualifies)
- Books not included:
- To Kill a Mockingbird (book_id = 2): All ratings are 4-5, no low ratings (≤2)
- Pride and Prejudice (book_id = 4): Only 2 sessions (< 5 minimum)
- The Catcher in the Rye (book_id = 5): Only 2 sessions (< 5 minimum)
The result table is ordered by polarization score in descending order, then by book title in descending order.
Approach overview
Problem Overview: You get a books table and a reading sessions table where each session has a rating. A book is polarized when its ratings split into two extremes, high and low, with enough sessions on both sides. You return the books that meet the polarization rule, so you need per-book counts of high and low sessions.
Approach 1: Per-Book Scan (O(B * S) time, O(B) space)
For each book, scan the full list of sessions and count how many ratings fall into the high range and how many fall into the low range. Then apply the polarization check to those two counts. This works, but it re-reads the session table once per book. When there are B books and S sessions, that is O(B * S) time. It shows you understand the rule, but it does not scale to large tables.
Approach 2: Join + Conditional Group Aggregation (O(S) time, O(B) space)
Join Books to the sessions on book_id, then group by the book. Inside each group, use conditional sums such as SUM(CASE WHEN rating >= 4 THEN 1 ELSE 0 END) for high and the matching expression for low. One pass over the sessions builds a hash table keyed by book, so every row is touched once. Filter the grouped result with a HAVING clause (or a Pandas boolean mask) that applies the polarization condition. Books with no sessions drop out, so use an inner join unless the rule explicitly requires them.
Recommended for interviews: Interviewers expect the group aggregation. The per-book scan proves you understand the rule, but the single-pass grouping with conditional counts shows you can turn a repeated lookup into one GROUP BY. Mention that the hash-based grouping is what keeps the solution linear. This pattern also appears in other database problems and in hash table counting questions.
If you solve it in Pandas, the same logic maps to merge, then groupby with sums of boolean masks, then a filter. Keep the join key explicit so you do not accidentally duplicate rows. For SQL-focused practice, the pattern lines up with SQL joins and aggregation.
Solution
Thinking
Polarization depends on rating extrema, session count, and the share of extreme scores, so books must be aggregated before filtering. Join
booksto sessions and group by book.One aggregation yields max, min, spread, session count, and the number of ratings
\le 2or\ge 4, then a half-up rounded polarization ratio.Keep books with at least five sessions, both a high and a low rating, and a ratio of at least
0.6, ordered by ratio then title, both descending.
We can implement this by joining the books table with the reading_sessions table, then grouping and aggregating the results.
First, we need to calculate the rating range, the number of extreme ratings, and the proportion of extreme ratings for each book.
Then, we can filter out books that meet the criteria based on these metrics.
Finally, sort the results by extreme rating proportion and book title in descending order.
# Write your MySQL query statement below
SELECT
book_id,
title,
author,
genre,
pages,
(MAX(session_rating) - MIN(session_rating)) AS rating_spread,
ROUND((SUM(session_rating <= 2) + SUM(session_rating >= 4)) / COUNT(1), 2) polarization_score
FROM
books
JOIN reading_sessions USING (book_id)
GROUP BY book_id
HAVING
COUNT(1) >= 5
AND MAX(session_rating) >= 4
AND MIN(session_rating) <= 2
AND 5 * (SUM(session_rating <= 2) + SUM(session_rating >= 4)) >= 3 * COUNT(1)
ORDER BY polarization_score DESC, title DESC;import pandas as pd
from decimal import Decimal, ROUND_HALF_UP
def find_polarized_books(
books: pd.DataFrame, reading_sessions: pd.DataFrame
) -> pd.DataFrame:
df = books.merge(reading_sessions, on="book_id")
agg_df = (
df.groupby(["book_id", "title", "author", "genre", "pages"])
.agg(
max_rating=("session_rating", "max"),
min_rating=("session_rating", "min"),
rating_spread=("session_rating", lambda x: x.max() - x.min()),
count_sessions=("session_rating", "count"),
low_or_high_count=("session_rating", lambda x: ((x <= 2) | (x >= 4)).sum()),
)
.reset_index()
)
agg_df["polarization_score"] = agg_df.apply(
lambda r: float(
(
Decimal(int(r["low_or_high_count"]))
/ Decimal(int(r["count_sessions"]))
).quantize(
Decimal("0.01"), rounding=ROUND_HALF_UP
)
),
axis=1,
)
result = agg_df[
(agg_df["count_sessions"] >= 5)
& (agg_df["max_rating"] >= 4)
& (agg_df["min_rating"] <= 2)
& (5 * agg_df["low_or_high_count"] >= 3 * agg_df["count_sessions"])
]
return result.sort_values(
by=["polarization_score", "title"], ascending=[False, False]
)[
[
"book_id",
"title",
"author",
"genre",
"pages",
"rating_spread",
"polarization_score",
]
]Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Per-Book Scan | O(B * S) | O(B) | Small tables or to verify logic before optimizing |
| Join + Conditional Group Aggregation | O(S) | O(B) | General case and production queries |
Frequently asked questions
Is Find Books with Polarized Opinions easy or hard?
It is rated Medium with an acceptance rate of about 46 percent. The difficulty comes from translating the polarization rule into conditional aggregation and handling the join correctly, not from complex logic. If you are comfortable with GROUP BY and CASE expressions, you can solve it in one pass.
Find Books with Polarized Opinions Python/Java solution?
In Python with Pandas, merge the books and sessions DataFrames on book_id, create boolean columns for high and low ratings, group by the book, sum those columns, and filter with a boolean mask. For Java or other languages, the same logic is expressed as a SQL query with a JOIN, GROUP BY, and HAVING clause. The FleetCode solution page provides both forms.
How to solve Find Books with Polarized Opinions in O(n)?
Join the books table to the sessions table, group by book_id, and compute high and low rating counts with conditional aggregation in one pass. Each session contributes to exactly one group, so the total work is linear in the number of sessions. Apply the polarization condition as a filter on the aggregated counts.
What is the best approach for Find Books with Polarized Opinions?
The best approach is a join between the books and reading sessions tables, followed by a single group aggregation. Use conditional sums to count high and low ratings per book, then filter with a HAVING clause or a Pandas mask. This runs in O(S) time, where S is the number of sessions.
What data structure is used in Find Books with Polarized Opinions?
The solution relies on a hash-based grouping structure, which the database engine or a Pandas groupby builds internally, keyed by book. Each group stores running high and low counts. No explicit tree or heap is needed.
What is the time complexity of Find Books with Polarized Opinions?
The optimal solution runs in O(S) time, where S is the number of reading sessions, because each session row is processed once during grouping. The space complexity is O(B), where B is the number of books, for the per-book aggregation results. A naive per-book scan takes O(B * S) time.
Is Find Books with Polarized Opinions asked at Google, Amazon, or Meta?
This problem is a Medium database question on LeetCode, and it is most relevant if you are preparing for SQL-heavy data roles or screens that include aggregation. Companies that test SQL in interviews, including large tech firms, often use joins and group-by questions of this type. Check recent company tag lists on LeetCode for confirmed frequency.
