A concert hall has n rows numbered from 0 to n - 1, each with m seats, numbered from 0 to m - 1. You need to design a ticketing system that can allocate seats in the following cases:
k spectators can sit together in a row.k spectators can get a seat. They may or may not sit together.Note that the spectators are very picky. Hence:
maxRow. maxRow can vary from group to group.Implement the BookMyShow class:
BookMyShow(int n, int m) Initializes the object with n as number of rows and m as number of seats per row.int[] gather(int k, int maxRow) Returns an array of length 2 denoting the row and seat number (respectively) of the first seat being allocated to the k members of the group, who must sit together. In other words, it returns the smallest possible r and c such that all [c, c + k - 1] seats are valid and empty in row r, and r <= maxRow. Returns [] in case it is not possible to allocate seats to the group.boolean scatter(int k, int maxRow) Returns true if all k members of the group can be allocated seats in rows 0 to maxRow, who may or may not sit together. If the seats can be allocated, it allocates k seats to the group with the smallest row numbers, and the smallest possible seat numbers in each row. Otherwise, returns false.Example 1:
Input
["BookMyShow", "gather", "gather", "scatter", "scatter"]
[[2, 5], [4, 0], [2, 0], [5, 1], [5, 1]]
Output
[null, [0, 0], [], true, false]
Explanation
BookMyShow bms = new BookMyShow(2, 5); // There are 2 rows with 5 seats each
bms.gather(4, 0); // return [0, 0]
// The group books seats [0, 3] of row 0.
bms.gather(2, 0); // return []
// There is only 1 seat left in row 0,
// so it is not possible to book 2 consecutive seats.
bms.scatter(5, 1); // return True
// The group books seat 4 of row 0 and seats [0, 3] of row 1.
bms.scatter(5, 1); // return False
// There is only one seat left in the hall.
Constraints:
1 <= n <= 5 * 1041 <= m, k <= 1090 <= maxRow <= n - 15 * 104 calls in total will be made to gather and scatter.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:
When booking concert tickets for groups, a brute-force method involves checking every possible arrangement of available seats to accommodate the group. This means we'll consider all combinations of seats, regardless of whether they are together or scattered. We'll examine each combination to see if it can fit the group and then choose the 'best' option.
Here's how the algorithm would work step-by-step:
def book_concert_tickets_brute_force(available_seats, group_size):
best_arrangement = None
# First, try to find a block of contiguous seats
for starting_seat_index in range(len(available_seats)):
if starting_seat_index + group_size <= len(available_seats):
seats_available = True
for i in range(starting_seat_index, starting_seat_index + group_size):
if not available_seats[i]:
seats_available = False
break
if seats_available:
arrangement = list(range(starting_seat_index, starting_seat_index + group_size))
if best_arrangement is None:
best_arrangement = arrangement
else:
#Simple proximity check: smaller index is closer to the stage
if arrangement[0] < best_arrangement[0]:
best_arrangement = arrangement
# Consider splitting the group if no contiguous block found
if best_arrangement is None:
#Iterate through all possible combinations of seats
import itertools
available_seat_indices = [i for i, seat in enumerate(available_seats) if seat]
for seat_combination in itertools.combinations(available_seat_indices, group_size):
if len(seat_combination) == group_size:
#Found an arrangement, so assess it based on the location.
arrangement = sorted(list(seat_combination))
if best_arrangement is None:
best_arrangement = arrangement
# Here, assess quality based on seat numbers (lower is better)
elif sum(arrangement) < sum(best_arrangement):
best_arrangement = arrangement
if best_arrangement:
#Mark tickets as booked
for booked_seat_index in best_arrangement:
available_seats[booked_seat_index] = False
return best_arrangementThe best way to book concert tickets in groups efficiently is to keep track of available seats and quickly find blocks of seats that fit the group size. We can use a special data structure that makes it easy to find the right block and update seat availability.
Here's how the algorithm would work step-by-step:
def book_concert_tickets(sections, group_size):
for section_index, section in enumerate(sections):
for row_index, row in enumerate(section):
if row >= group_size:
# Find a continuous block of empty seats
seats = find_continuous_block(sections, section_index, row_index, group_size)
if seats:
return seats
# If no single row has enough seats, try multiple adjacent rows
for section_index, section in enumerate(sections):
seats = find_multiple_rows(sections, section_index, group_size)
if seats:
return seats
return None
def find_continuous_block(sections, section_index, row_index, group_size):
section = sections[section_index]
row = section[row_index]
if row >= group_size:
sections[section_index][row_index] -= group_size
return (section_index, row_index, group_size)
return None
def find_multiple_rows(sections, section_index, group_size):
rows = []
for row_index, row in enumerate(sections[section_index]):
rows.append((row_index, row))
for i in range(len(rows)):
total_seats = 0
selected_rows = []
for j in range(i, len(rows)):
row_index, available_seats = rows[j]
total_seats += available_seats
selected_rows.append(row_index)
if total_seats >= group_size:
# Allocate seats from multiple rows
seats_allocated = allocate_seats_from_rows(sections, section_index, selected_rows, group_size)
if seats_allocated:
return seats_allocated
return None
def allocate_seats_from_rows(sections, section_index, selected_rows, group_size):
seats_allocated = []
remaining_seats = group_size
for row_index in selected_rows:
available_seats = sections[section_index][row_index]
seats_to_allocate = min(remaining_seats, available_seats)
# Update number of available seats
sections[section_index][row_index] -= seats_to_allocate
seats_allocated.append((section_index, row_index, seats_to_allocate))
remaining_seats -= seats_to_allocate
if remaining_seats == 0:
return seats_allocated
return None| Case | How to Handle |
|---|---|
| seatsAvailable is null or empty | Return an empty list or throw an exception, depending on the defined API contract. |
| groupSize is zero or negative | Throw an IllegalArgumentException as a zero or negative group size is invalid. |
| seatsAvailable contains extremely large numbers (potential integer overflow) | Use long data type to avoid integer overflow and handle potential out-of-memory errors gracefully. |
| groupSize is larger than the total number of seats available in the system | Return an empty list or throw an exception since the request cannot be fulfilled. |
| Multiple groups can fit, but only one is required | Return the first available booking (e.g., lowest index) that fits the entire group. |
| No available seats that can accommodate the group | Return an empty list to indicate no suitable booking exists. |
| seatsAvailable array contains only zero values | Return an empty list because no seat can accommodate any group size greater than 0. |
| Seats are fragmented such that there are enough total seats, but not enough contiguous seats for the group. | The algorithm needs to correctly search for contiguous blocks and return empty if no sufficient block exists. |