LeetCode 2026 - Low-Quality Problems

The problem gives us a database table named Problems. Each row represents a LeetCode problem and contains three columns:

LeetCode Problem 2026

Difficulty: 🟢 Easy
Topics: Database

Solution

Problem Understanding

The problem gives us a database table named Problems. Each row represents a LeetCode problem and contains three columns:

Column Meaning
problem_id Unique identifier for the problem
likes Number of users who liked the problem
dislikes Number of users who disliked the problem

We must identify all problems whose like percentage is strictly less than 60%.

The like percentage is defined as:

$$\frac{\text{likes}}{\text{likes} + \text{dislikes}} \times 100$$

A problem is considered low-quality if this percentage is less than 60.

The output should contain only the problem_id values of such problems, sorted in ascending order.

This is fundamentally a filtering problem. For every row in the table, we compute the ratio of likes to total votes and check whether it falls below the threshold.

The input scale is very small compared to algorithm-heavy problems because this is a SQL database problem. We are not dealing with millions of operations in code. Instead, the focus is on correctly expressing the filtering condition in SQL.

An important observation is that the condition is strictly less than 60%. If a problem has exactly 60% likes, it should not be included in the result.

Another subtle point is integer division. In SQL, dividing integers may truncate decimals depending on the database system. A naive implementation using integer division can produce incorrect results. We must ensure decimal arithmetic is used.

The problem guarantees that each row has a valid problem_id, and the total votes are meaningful. Since the percentage formula divides by (likes + dislikes), we assume the denominator is nonzero.

Approaches

Brute Force Approach

The brute-force way is to process every row one by one, compute the like percentage manually, and then collect all rows where the percentage is below 60.

Conceptually, this means:

  1. Read every row from the table.
  2. Compute:

$$\frac{\text{likes}}{\text{likes} + \text{dislikes}} \times 100$$ 3. Compare the result against 60. 4. Keep matching problem_id values. 5. Sort the final result.

This approach is correct because every problem is independently evaluated against the exact definition of a low-quality problem.

However, in database systems, manually iterating row by row outside SQL is inefficient and unnecessary. Databases are optimized for declarative filtering operations using WHERE clauses.

Optimal Approach

The key insight is that SQL databases are designed to efficiently filter rows using arithmetic expressions directly inside the query.

Instead of external iteration, we can express the condition directly:

likes / (likes + dislikes) < 0.6

To avoid integer division issues, we convert one operand into a decimal value:

likes * 1.0 / (likes + dislikes)

This guarantees floating-point arithmetic.

The database engine evaluates the condition for each row internally and returns only the matching rows.

Approach Comparison

Approach Time Complexity Space Complexity Notes
Brute Force O(n) O(n) Iterates manually through all rows and stores results
Optimal O(n) O(1) Uses SQL filtering directly in the database engine

Algorithm Walkthrough

  1. Start by selecting rows from the Problems table.
  2. For each row, compute the like ratio using:

$$\frac{\text{likes}}{\text{likes} + \text{dislikes}}$$ 3. Convert the division into floating-point arithmetic by multiplying likes by 1.0. This prevents integer truncation. 4. Compare the computed ratio against 0.6. 5. Keep only rows where the ratio is strictly less than 0.6. 6. Return only the problem_id column. 7. Sort the output by problem_id in ascending order.

Why it works

The algorithm directly implements the mathematical definition of a low-quality problem. Every row is checked independently using the exact percentage condition. Since SQL evaluates the filtering condition for all rows, every qualifying problem is included exactly once, and every non-qualifying problem is excluded.

Python Solution

Although this is a database problem and normally solved with SQL, the equivalent Python logic can be written as follows.

from typing import List

class Solution:
    def lowQualityProblems(
        self,
        problems: List[List[int]]
    ) -> List[int]:
        result: List[int] = []

        for problem_id, likes, dislikes in problems:
            total_votes = likes + dislikes
            like_ratio = likes / total_votes

            if like_ratio < 0.6:
                result.append(problem_id)

        result.sort()

        return result

The implementation iterates through every problem entry and computes the like ratio using floating-point division.

The variable total_votes stores the denominator, which is the total number of likes and dislikes combined.

The variable like_ratio represents the fraction of users who liked the problem.

If the ratio is strictly less than 0.6, the problem_id is appended to the result list.

Finally, the result is sorted before returning, matching the required output ordering.

For the actual LeetCode database submission, the SQL query is:

SELECT problem_id
FROM Problems
WHERE likes * 1.0 / (likes + dislikes) < 0.6
ORDER BY problem_id;

Go Solution

package main

import (
	"sort"
)

type Solution struct{}

func (s Solution) lowQualityProblems(problems [][]int) []int {
	result := []int{}

	for _, problem := range problems {
		problemID := problem[0]
		likes := problem[1]
		dislikes := problem[2]

		totalVotes := likes + dislikes
		likeRatio := float64(likes) / float64(totalVotes)

		if likeRatio < 0.6 {
			result = append(result, problemID)
		}
	}

	sort.Ints(result)

	return result
}

The Go version follows the same logic as the Python implementation.

One important Go-specific detail is explicit type conversion. Integer division in Go truncates decimals, so both operands must be converted to float64 before division.

The result slice is dynamically expanded using append, and sort.Ints is used to ensure ascending order.

For the actual LeetCode database solution, the SQL remains:

SELECT problem_id
FROM Problems
WHERE likes * 1.0 / (likes + dislikes) < 0.6
ORDER BY problem_id;

Worked Examples

Example 1

Input table:

problem_id likes dislikes
6 1290 425
11 2677 8659
1 4446 2760
7 8569 6086
13 2050 4164
10 9002 7446

We process each row individually.

problem_id likes dislikes total_votes like_ratio Low Quality?
6 1290 425 1715 0.7522 No
11 2677 8659 11336 0.2361 Yes
1 4446 2760 7206 0.6169 No
7 8569 6086 14655 0.5847 Yes
13 2050 4164 6214 0.3299 Yes
10 9002 7446 16448 0.5473 Yes

Collected low-quality IDs:

[11, 7, 13, 10]

After sorting:

[7, 10, 11, 13]

Final output:

problem_id
7
10
11
13

Complexity Analysis

Measure Complexity Explanation
Time O(n) Each problem row is processed once
Space O(1) Aside from output storage, only constant extra memory is used

The database query scans all rows exactly once and applies a constant-time arithmetic computation to each row. No additional data structures are required.

Test Cases

def low_quality(problems):
    result = []

    for problem_id, likes, dislikes in problems:
        if likes / (likes + dislikes) < 0.6:
            result.append(problem_id)

    return sorted(result)

# Provided example
assert low_quality([
    [6, 1290, 425],
    [11, 2677, 8659],
    [1, 4446, 2760],
    [7, 8569, 6086],
    [13, 2050, 4164],
    [10, 9002, 7446]
]) == [7, 10, 11, 13]  # standard mixed case

# Exactly 60%, should NOT be included
assert low_quality([
    [1, 60, 40]
]) == []  # strict inequality check

# Below 60%
assert low_quality([
    [1, 59, 41]
]) == [1]  # just below threshold

# Above 60%
assert low_quality([
    [1, 61, 39]
]) == []  # just above threshold

# Single row low quality
assert low_quality([
    [5, 1, 9]
]) == [5]  # extremely low ratio

# Single row high quality
assert low_quality([
    [5, 9, 1]
]) == []  # extremely high ratio

# Multiple unsorted IDs
assert low_quality([
    [10, 1, 9],
    [2, 2, 8],
    [7, 9, 1]
]) == [2, 10]  # verifies sorting

# All low quality
assert low_quality([
    [1, 1, 9],
    [2, 2, 8],
    [3, 3, 7]
]) == [1, 2, 3]  # every row qualifies

# No low-quality problems
assert low_quality([
    [1, 10, 1],
    [2, 20, 2]
]) == []  # empty result

Test Summary

Test Why
Provided example Verifies standard functionality
Exactly 60% Ensures strict inequality is handled correctly
Just below 60% Validates boundary inclusion
Just above 60% Validates boundary exclusion
Single low-quality row Tests minimal qualifying input
Single high-quality row Tests minimal non-qualifying input
Unsorted IDs Confirms final sorting behavior
All low-quality Ensures every row can qualify
No low-quality rows Ensures empty output works correctly

Edge Cases

Problems With Exactly 60% Likes

A common mistake is using <= 0.6 instead of < 0.6. The problem explicitly states that low-quality problems must have a percentage strictly less than 60%.

For example:

likes = 60
dislikes = 40

The ratio is exactly 0.6, so this problem must not appear in the result.

The implementation correctly uses a strict comparison.

Integer Division Errors

In many SQL engines and programming languages, dividing integers truncates decimal values.

For example:

1 / 2 = 0

instead of:

0.5

If integer division is used accidentally, many ratios become incorrect, leading to wrong filtering results.

The SQL solution avoids this by using:

likes * 1.0 / (likes + dislikes)

which forces floating-point arithmetic.

Empty Result Set

It is possible that no problems satisfy the low-quality condition.

For example:

[1, 10, 1]
[2, 20, 2]

Both problems have like percentages greater than 60%.

The implementation correctly returns an empty result without errors or special-case handling.