Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Booking Concert Tickets in Groups

Updated
5 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "2286" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

Problem Statement

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: If a group of k spectators can sit together in a row. If every member of a group of k spectators can get a seat. They may or may not sit together. Note that the spectators are very picky. Hence: They will book seats only if each member of their group can get a seat with row number less than or equal to maxRow. maxRow can vary from group to group. In case there are multiple rows to choose from, the row with the smallest number is chosen. If there are multiple seats to choose in the same row, the seat with the smallest number is chosen. 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 104 1 <= m, k <= 109 0 <= maxRow <= n - 1 At most 5 104 calls in total will be made to gather and scatter.

Explanation

Here's a breakdown of the approach, followed by the Python code:

  • Segment Tree for Gather: Use a segment tree to efficiently find a contiguous block of k available seats in a row within the maxRow limit. The segment tree stores the maximum contiguous available seats in each segment.
  • Prefix Sum for Scatter: Employ a prefix sum array to track the total available seats up to each row. This enables efficient checking if enough seats exist within maxRow for the scatter operation.
  • Lazy Propagation for Updates: Utilize lazy propagation in the segment tree to efficiently update ranges of seat availability after allocation.

  • Runtime Complexity: O(n log n) for initialization, O(log n) for gather and scatter operations. Storage Complexity: O(n)

Code

    class BookMyShow:

    def __init__(self, n: int, m: int):
        self.n = n
        self.m = m
        self.tree = [0] * (4 * n)
        self.lazy = [0] * (4 * n)
        self.seats = [m] * n
        self.total_seats = [m] * n
        self.build(1, 0, n - 1)

    def build(self, node, start, end):
        if start == end:
            self.tree[node] = self.m
            return
        mid = (start + end) // 2
        self.build(node * 2, start, mid)
        self.build(node * 2 + 1, mid + 1, end)
        self.tree[node] = max(self.tree[node * 2], self.tree[node * 2 + 1])

    def push(self, node, start, end):
        if self.lazy[node] != 0:
            self.tree[node] -= self.lazy[node]
            if start != end:
                self.lazy[node * 2] += self.lazy[node]
                self.lazy[node * 2 + 1] += self.lazy[node]
            self.lazy[node] = 0

    def update(self, node, start, end, l, r, val):
        self.push(node, start, end)
        if start > r or end < l:
            return
        if l <= start and end <= r:
            self.lazy[node] += val
            self.push(node, start, end)
            return
        mid = (start + end) // 2
        self.update(node * 2, start, mid, l, r, val)
        self.update(node * 2 + 1, mid + 1, end, l, r, val)
        self.tree[node] = max(self.tree[node * 2], self.tree[node * 2 + 1])

    def query(self, node, start, end, l, r):
        self.push(node, start, end)
        if start > r or end < l:
            return 0
        if l <= start and end <= r:
            return self.tree[node]
        mid = (start + end) // 2
        return max(self.query(node * 2, start, mid, l, r), self.query(node * 2 + 1, mid + 1, end, l, r))

    def gather(self, k: int, maxRow: int) -> list[int]:
        for i in range(maxRow + 1):
          available = self.seats[i]
          if available >= k:
            self.seats[i] -= k
            self.update(1, 0, self.n - 1, i, i, k)
            return [i, self.total_seats[i] - available]

        return []

    def scatter(self, k: int, maxRow: int) -> bool:
        available_seats = 0
        for i in range(maxRow + 1):
          available_seats += self.seats[i]

        if available_seats < k:
          return False

        for i in range(maxRow + 1):
          take = min(k, self.seats[i])
          self.seats[i] -= take
          self.update(1, 0, self.n - 1, i, i, take)
          k -= take
          if k == 0:
            break
        return True

More from this blog

C

Chatmagic blog

2894 posts