Find Overbooked Employees solution and explanation
5 more videos on this problem
Leetcode MEDIUM 3611 - Weeks Starting Monday vs Sunday & CTE in SQL - Overbooked Employees | EDSEveryday Data Science · 10:43 · 950 views
3611. Find Overbooked EmployeesData Portfolio · 18:37 · 42 views
Find Overbooked Employees | SQL Window Functions & Aggregation (LeetCode 3611 – Medium)Vivek The Analyst · 13:01 · 42 views
Leetcode 3611 Find Overbooked Employees - Best SQL Explanation Available Online!AlgorithmicIQ · 11:19 · 15 views
LeetCode, Pandas, 3611. Find Overbooked Employees, MediumДиванная аналитика · 24:53 · 6 views
LeetCode, SQL, 3611. Find Overbooked Employees, MediumДиванная аналитика · 20:27 · 3 views
The problem
Table: employees
+---------------+---------+ | Column Name | Type | +---------------+---------+ | employee_id | int | | employee_name | varchar | | department | varchar | +---------------+---------+ employee_id is the unique identifier for this table. Each row contains information about an employee and their department.
Table: meetings
+---------------+---------+ | Column Name | Type | +---------------+---------+ | meeting_id | int | | employee_id | int | | meeting_date | date | | meeting_type | varchar | | duration_hours| decimal | +---------------+---------+ meeting_id is the unique identifier for this table. Each row represents a meeting attended by an employee. meeting_type can be 'Team', 'Client', or 'Training'.
Write a solution to find employees who are meeting-heavy - employees who spend more than 50% of their working time in meetings during any given week.
- Assume a standard work week is
40hours - Calculate total meeting hours per employee per week (Monday to Sunday)
- An employee is meeting-heavy if their weekly meeting hours
>20hours (50%of40hours) - Count how many weeks each employee was meeting-heavy
- Only include employees who were meeting-heavy for at least
2weeks
Return the result table ordered by the number of meeting-heavy weeks in descending order, then by employee name in ascending order.
The result format is in the following example.
Example:
Input:
employees table:
+-------------+----------------+-------------+ | employee_id | employee_name | department | +-------------+----------------+-------------+ | 1 | Alice Johnson | Engineering | | 2 | Bob Smith | Marketing | | 3 | Carol Davis | Sales | | 4 | David Wilson | Engineering | | 5 | Emma Brown | HR | +-------------+----------------+-------------+
meetings table:
+------------+-------------+--------------+--------------+----------------+ | meeting_id | employee_id | meeting_date | meeting_type | duration_hours | +------------+-------------+--------------+--------------+----------------+ | 1 | 1 | 2023-06-05 | Team | 8.0 | | 2 | 1 | 2023-06-06 | Client | 6.0 | | 3 | 1 | 2023-06-07 | Training | 7.0 | | 4 | 1 | 2023-06-12 | Team | 12.0 | | 5 | 1 | 2023-06-13 | Client | 9.0 | | 6 | 2 | 2023-06-05 | Team | 15.0 | | 7 | 2 | 2023-06-06 | Client | 8.0 | | 8 | 2 | 2023-06-12 | Training | 10.0 | | 9 | 3 | 2023-06-05 | Team | 4.0 | | 10 | 3 | 2023-06-06 | Client | 3.0 | | 11 | 4 | 2023-06-05 | Team | 25.0 | | 12 | 4 | 2023-06-19 | Client | 22.0 | | 13 | 5 | 2023-06-05 | Training | 2.0 | +------------+-------------+--------------+--------------+----------------+
Output:
+-------------+----------------+-------------+---------------------+ | employee_id | employee_name | department | meeting_heavy_weeks | +-------------+----------------+-------------+---------------------+ | 1 | Alice Johnson | Engineering | 2 | | 4 | David Wilson | Engineering | 2 | +-------------+----------------+-------------+---------------------+
Explanation:
- Alice Johnson (employee_id = 1):
- Week of June 5-11 (2023-06-05 to 2023-06-11): 8.0 + 6.0 + 7.0 = 21.0 hours (> 20 hours)
- Week of June 12-18 (2023-06-12 to 2023-06-18): 12.0 + 9.0 = 21.0 hours (> 20 hours)
- Meeting-heavy for 2 weeks
- David Wilson (employee_id = 4):
- Week of June 5-11: 25.0 hours (> 20 hours)
- Week of June 19-25: 22.0 hours (> 20 hours)
- Meeting-heavy for 2 weeks
- Employees not included:
- Bob Smith (employee_id = 2): Week of June 5-11: 15.0 + 8.0 = 23.0 hours (> 20), Week of June 12-18: 10.0 hours (< 20). Only 1 meeting-heavy week
- Carol Davis (employee_id = 3): Week of June 5-11: 4.0 + 3.0 = 7.0 hours (< 20). No meeting-heavy weeks
- Emma Brown (employee_id = 5): Week of June 5-11: 2.0 hours (< 20). No meeting-heavy weeks
The result table is ordered by meeting_heavy_weeks in descending order, then by employee name in ascending order.
Approach overview
Problem Overview: You have employee and meeting records. Return the employees who are overbooked, meaning their meeting activity crosses the defined threshold. The output must include the employee identity fields, so you need to combine aggregated meeting data with the employee table.
Approach 1: Correlated Subquery per Employee (O(n × m) time, O(1) extra space)
For each employee row, run a subquery that counts or sums that employee's meetings and filter on the threshold. The database re-scans the meetings table for every employee, so the work grows with the number of employees times the number of meetings. This version is easy to write and correct on small tables. It breaks down once both tables grow, because the same meeting rows get read again and again.
Approach 2: GROUP BY Aggregation + JOIN (O(n + m) time, O(n) space)
Scan the meetings table once and group by employee_id. Compute the aggregate you need, such as COUNT(*) or SUM(duration), and apply the overbooking condition in a HAVING clause. Then join the grouped result to the employees table on employee_id to pull names and other fields. The hash-based grouping makes one pass over meetings, and the join costs roughly linear time with a hash join or indexed lookup. Use this approach by default. It scales with table size and is the form most database interviewers expect.
If the threshold depends on a time window, such as a per-day or per-month limit, add that column to the GROUP BY. Group by employee and window together, then filter. Watch for employees with no meetings. Use an INNER JOIN only if they cannot be overbooked, since an empty group never passes the threshold anyway.
Recommended for interviews: Write the correlated subquery first to show you understand the filter logic. Then rewrite it as a single GROUP BY with HAVING and a join. The brute force shows you can read the requirements. The aggregation version shows you can reason about query cost and clean set-based SQL. Explain how you would index employee_id on the meetings table to keep the join fast. For more practice, see database problems and aggregation problems.
Solution
Thinking
A meeting-heavy week is a sum over an ISO year-week, not a single day. Convert dates to year and week, then sum
durationby(employee_id,year,week).Keep weeks with at least
20hours, count them per employee, join those with at least two such weeks to the employee table, and sort by the count descending then name ascending.The aggregation key must include the year, otherwise the same week number in different years would merge.
First, we group the data by employee_id, year, and week to calculate the total meeting hours for each employee in each week. Then, we filter out the weeks where the meeting hours exceed 20 and count the number of meeting-heavy weeks for each employee. Finally, we join the result with the employees table, filter out employees with at least 2 meeting-heavy weeks, and sort the results as required.
# Write your MySQL query statement below
WITH
week_meeting_hours AS (
SELECT
employee_id,
YEAR(meeting_date) AS year,
WEEK(meeting_date, 1) AS week,
SUM(duration_hours) hours
FROM meetings
GROUP BY 1, 2, 3
),
intensive_weeks AS (
SELECT
employee_id,
employee_name,
department,
count(1) AS meeting_heavy_weeks
FROM
week_meeting_hours
JOIN employees USING (employee_id)
WHERE hours >= 20
GROUP BY 1
)
SELECT employee_id, employee_name, department, meeting_heavy_weeks
FROM intensive_weeks
WHERE meeting_heavy_weeks >= 2
ORDER BY 4 DESC, 2;import pandas as pd
def find_overbooked_employees(
employees: pd.DataFrame, meetings: pd.DataFrame
) -> pd.DataFrame:
meetings["meeting_date"] = pd.to_datetime(meetings["meeting_date"])
meetings["year"] = meetings["meeting_date"].dt.isocalendar().year
meetings["week"] = meetings["meeting_date"].dt.isocalendar().week
week_meeting_hours = (
meetings.groupby(["employee_id", "year", "week"], as_index=False)[
"duration_hours"
]
.sum()
.rename(columns={"duration_hours": "hours"})
)
intensive_weeks = week_meeting_hours[week_meeting_hours["hours"] >= 20]
intensive_count = (
intensive_weeks.groupby("employee_id")
.size()
.reset_index(name="meeting_heavy_weeks")
)
result = intensive_count.merge(employees, on="employee_id")
result = result[result["meeting_heavy_weeks"] >= 2]
result = result.sort_values(
["meeting_heavy_weeks", "employee_name"], ascending=[False, True]
)
return result[
["employee_id", "employee_name", "department", "meeting_heavy_weeks"]
].reset_index(drop=True)Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Correlated Subquery | O(n × m) | O(1) extra | Small tables or quick prototyping |
| GROUP BY + JOIN | O(n + m) | O(n) for groups | General case and production queries |
Frequently asked questions
Is Find Overbooked Employees easy or hard?
It is rated Medium with a 45.2% acceptance rate. The logic is straightforward once you see that grouping and filtering solve it. Most difficulty comes from handling the join and the threshold condition correctly without double counting or dropping employees.
Find Overbooked Employees Python/Java solution
This is a SQL problem, so the solution is written as a query rather than in Python or Java. The Pandas version uses groupby with agg to compute the totals, filters with a boolean mask, and merges with the employees DataFrame on employee_id. The SQL version uses GROUP BY, HAVING, and an INNER JOIN.
How to solve Find Overbooked Employees in O(n)?
Group the meetings by employee_id in one pass and compute the required aggregate for each group. Filter the groups with HAVING to keep only overbooked employees. Then join the result to the employees table on employee_id to return the final rows. A hash-based aggregation keeps the grouping step linear.
What is the best approach for Find Overbooked Employees?
The best approach is a GROUP BY aggregation with a HAVING filter, joined to the employees table to return names. It makes a single pass over the meetings data, so it runs in O(n + m) time. This is the standard set-based SQL solution for this problem.
Is Find Overbooked Employees asked at Google/Amazon/Meta?
Company tags for this problem are not listed on FleetCode, so we cannot confirm which companies ask it. It is a Medium SQL problem in the Database category, which matches the style of data-analysis questions common in SQL rounds. Check recent interview reports for current company-specific data.
What data structure is used in Find Overbooked Employees?
The solution relies on relational tables and a grouped intermediate result, not a traditional data structure. The database engine uses a hash table or sort to perform GROUP BY, and a hash join or index lookup to combine the grouped result with the employees table.
What is the time complexity of Find Overbooked Employees?
The optimal GROUP BY and JOIN solution runs in O(n + m) time, where n is the number of employees and m is the number of meeting records. The correlated subquery alternative runs in O(n × m) time because it rescans the meetings table for each employee.
