
A cinema has n rows of seats, numbered from 1 to n and there are ten seats in each row, labelled from 1 to 10 as shown in the figure above.
Given the array reservedSeats containing the numbers of seats already reserved, for example, reservedSeats[i] = [3,8] means the seat located in row 3 and labelled with 8 is already reserved.
Return the maximum number of four-person groups you can assign on the cinema seats. A four-person group occupies four adjacent seats in one single row. Seats across an aisle (such as [3,3] and [3,4]) are not considered to be adjacent, but there is an exceptional case on which an aisle split a four-person group, in that case, the aisle split a four-person group in the middle, which means to have two people on each side.
Example 1:

Input: n = 3, reservedSeats = [[1,2],[1,3],[1,8],[2,6],[3,1],[3,10]] Output: 4 Explanation: The figure above shows the optimal allocation for four groups, where seats mark with blue are already reserved and contiguous seats mark with orange are for one group.
Example 2:
Input: n = 2, reservedSeats = [[2,1],[1,8],[2,6]] Output: 2
Example 3:
Input: n = 4, reservedSeats = [[4,3],[1,4],[4,6],[1,7]] Output: 4
Constraints:
1 <= n <= 10^91 <= reservedSeats.length <= min(10*n, 10^4)reservedSeats[i].length == 21 <= reservedSeats[i][0] <= n1 <= reservedSeats[i][1] <= 10reservedSeats[i] are distinct.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem involves checking every single possible arrangement of families in the cinema rows. We will examine each row and try placing families in all possible combinations of seats. This exhaustive search guarantees we find the best arrangement, albeit inefficiently.
Here's how the algorithm would work step-by-step:
def cinema_seat_allocation_brute_force(number_of_rows, reserved_seats):
maximum_families = 0
# Consider all possible arrangements of families
for i in range(2 ** (number_of_rows * 10)):
number_of_families_seated = 0
row_allocations = {}
# For each row, determine which seats are occupied based on 'i'
for row_number in range(1, number_of_rows + 1):
row_allocations[row_number] = [False] * 10
temp_value = i
for row_number in range(1, number_of_rows + 1):
for seat_number in range(1, 11):
if temp_value % 2 == 1:
row_allocations[row_number][seat_number-1] = True
temp_value //= 2
# Check if the allocation is valid based on reserved seats
is_valid = True
for row_number, seat_number in reserved_seats:
if row_number in row_allocations and seat_number >= 1 and seat_number <= 10 and row_allocations[row_number][seat_number-1]:
is_valid = False
break
if not is_valid:
continue
# Count how many families can be seated in each row
for row_number in range(1, number_of_rows + 1):
can_seat_families = 0
seats = row_allocations[row_number]
# Seats 2-5
if not any(seats[1:5]):
can_seat_families += 1
# Seats 4-7
if not any(seats[3:7]):
can_seat_families += 1
# Seats 6-9
if not any(seats[5:9]):
can_seat_families += 1
number_of_families_seated += can_seat_families
# Update the maximum families seated
maximum_families = max(maximum_families, number_of_families_seated)
return maximum_familiesThe most efficient approach is to focus on each row independently and maximize the number of families that can be seated. We avoid unnecessary calculations by considering only rows with reserved seats and cleverly grouping the remaining seats.
Here's how the algorithm would work step-by-step:
def max_number_of_families(number_of_rows: int, reserved_seats: list[list[int]]) -> int:
rows_with_reservations = {}
for reservation in reserved_seats:
row_number = reservation[0]
seat_number = reservation[1]
if row_number not in rows_with_reservations:
rows_with_reservations[row_number] = [False] * 10
rows_with_reservations[row_number][seat_number - 1] = True
number_of_unreserved_rows = number_of_rows - len(rows_with_reservations)
total_families = number_of_unreserved_rows * 2
for row_number, seats in rows_with_reservations.items():
families_in_row = 0
# Try to fit a family in seats 2-5
if not any(seats[1:5]):
families_in_row += 1
# Try to fit a family in seats 6-9
if not any(seats[5:9]):
families_in_row += 1
# Try to fit a family across the aisle in seats 4-7
# Only attempt this if the other two options failed. We don't want to double count
if families_in_row == 0 and not any(seats[3:7]):
families_in_row += 1
total_families += families_in_row
return total_families| Case | How to Handle |
|---|---|
| Null or empty input: n (number of rows) is zero or negative. | Return 0 immediately, as no rows exist to allocate seats. |
| Empty reserved seats array. | Return n * 2, as all rows are fully available for family seating. |
| Maximum number of rows (n is very large). | The solution should use a space-efficient data structure (e.g., a map or hash table) to store reserved seats, avoiding the creation of a large, dense array; avoid solutions with O(n) space complexity where possible |
| Reserved seats clustered in a few rows, leaving most rows empty. | Iterating through reserved seats avoids unnecessary processing of empty rows; the solution should only process rows that have reservations. |
| Reserved seats scattered across all columns in a row, blocking all family seating. | The bitmask or direct checks should accurately determine when all possible family arrangements in a row are blocked. |
| Reserved seats with invalid row or column numbers (e.g., row > n, column < 1, column > 10). | Ignore or sanitize such invalid seat reservations, assuming 1-based indexing with column restrictions (1-10). |
| Duplicate reserved seats. | Treat these as a single reservation as they don't affect the availability of family seats. |
| Integer overflow in intermediate calculations (if applicable). | Ensure all intermediate calculations and results remain within the acceptable integer range to avoid incorrect seat allocation counts. |