Facebook Pixel

1109. Corporate Flight Bookings

Problem Description

You have n flights numbered from 1 to n.

You're given an array called bookings where each element bookings[i] = [first_i, last_i, seats_i] represents a booking that reserves seats_i seats on every flight from flight number first_i to flight number last_i (inclusive).

Your task is to return an array answer of length n, where answer[i] tells you the total number of seats reserved for flight i.

For example, if you have a booking [1, 3, 10], it means 10 seats are reserved on flights 1, 2, and 3. If another booking is [2, 4, 20], then 20 additional seats are reserved on flights 2, 3, and 4. The final answer would show the cumulative seats reserved for each flight after processing all bookings.

The solution uses a difference array technique. Instead of updating every flight in the range [first, last] individually (which would be inefficient), it marks the start and end of each booking range. It adds seats at position first - 1 (converting to 0-indexed) and subtracts seats at position last (which is one position after the last flight in the range). After processing all bookings this way, a prefix sum calculation using accumulate gives the final seat count for each flight.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The naive approach would be to iterate through each booking and add the seats to every flight in the range [first, last]. However, this would take O(m × k) time where m is the number of bookings and k is the average range size, which can be inefficient when ranges are large.

The key insight is recognizing that we're performing the same operation (adding a constant value) to a contiguous range of elements multiple times. This is a classic scenario for the difference array technique.

Think of it like turning lights on and off in a hallway. Instead of walking to each light switch individually, you could just mark where the lit section starts and where it ends. When you walk through the hallway later, you know which lights should be on based on these markers.

Similarly, for each booking range [first, last] with seats seats:

  • We mark the beginning of the range by adding seats at position first - 1
  • We mark the end of the range by subtracting seats at position last (the position right after the range ends)

Why does this work? When we compute the prefix sum later:

  • At position first - 1, the running sum increases by seats
  • This increased value carries forward to all subsequent positions
  • At position last, the running sum decreases by seats, effectively "turning off" the addition for flights beyond the range

This transforms an O(m × k) problem into an O(m + n) problem, where we only need O(m) operations to process all bookings and O(n) to compute the final prefix sum.

Learn more about Prefix Sum patterns.

Solution Approach

The solution implements the difference array technique to efficiently handle range updates:

Step 1: Initialize the difference array

ans = [0] * n

We create an array of size n initialized with zeros to store our difference values.

Step 2: Process each booking

for first, last, seats in bookings:
    ans[first - 1] += seats
    if last < n:
        ans[last] -= seats

For each booking [first, last, seats]:

  • Add seats at index first - 1 (converting from 1-indexed to 0-indexed). This marks the start of the range where seats are added.
  • Subtract seats at index last (which is last + 1 in 1-indexed terms, but just last in 0-indexed). This marks where the seat addition should stop.
  • The condition if last < n ensures we don't go out of bounds when the booking extends to the last flight.

Step 3: Calculate prefix sum

return list(accumulate(ans))

The accumulate function computes the running sum of the difference array. Each position i in the result contains the sum of all values from index 0 to i in the difference array.

Why this works: When we compute the prefix sum:

  • At any index i, the value represents the cumulative effect of all "start" markers before or at i minus all "end" markers before i
  • This automatically gives us the total seats reserved for flight i + 1

Time Complexity: O(m + n) where m is the number of bookings and n is the number of flights Space Complexity: O(n) for the answer array

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a small example with n = 5 flights and the following bookings:

  • bookings = [[1, 3, 10], [2, 4, 20], [2, 5, 25]]

Step 1: Initialize difference array

ans = [0, 0, 0, 0, 0]

Step 2: Process each booking

Booking 1: [1, 3, 10] - Reserve 10 seats on flights 1-3

  • Add 10 at index 0 (flight 1, converted to 0-indexed)
  • Subtract 10 at index 3 (one position after flight 3)
ans = [10, 0, 0, -10, 0]

Booking 2: [2, 4, 20] - Reserve 20 seats on flights 2-4

  • Add 20 at index 1 (flight 2, converted to 0-indexed)
  • Subtract 20 at index 4 (one position after flight 4)
ans = [10, 20, 0, -10, -20]

Booking 3: [2, 5, 25] - Reserve 25 seats on flights 2-5

  • Add 25 at index 1 (flight 2, converted to 0-indexed)
  • Since last = 5 equals n, we skip the subtraction (no flights after 5)
ans = [10, 45, 0, -10, -20]

Step 3: Calculate prefix sum Computing the running sum:

  • Index 0: 10
  • Index 1: 10 + 45 = 55
  • Index 2: 55 + 0 = 55
  • Index 3: 55 + (-10) = 45
  • Index 4: 45 + (-20) = 25

Final Result:

answer = [10, 55, 55, 45, 25]

This means:

  • Flight 1: 10 seats reserved (from booking 1)
  • Flight 2: 55 seats reserved (10 from booking 1 + 20 from booking 2 + 25 from booking 3)
  • Flight 3: 55 seats reserved (10 from booking 1 + 20 from booking 2 + 25 from booking 3)
  • Flight 4: 45 seats reserved (20 from booking 2 + 25 from booking 3)
  • Flight 5: 25 seats reserved (only from booking 3)

The difference array technique efficiently handles all range updates in O(m) time and computes the final answer in O(n) time, avoiding the need to update each flight individually for every booking.

Solution Implementation

1from typing import List
2from itertools import accumulate
3
4class Solution:
5    def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:
6        # Initialize difference array with n elements, all set to 0
7        # This will store the seat changes at each flight position
8        difference_array = [0] * n
9      
10        # Process each booking
11        for first_flight, last_flight, seats_to_add in bookings:
12            # Add seats at the start of the booking range (convert to 0-indexed)
13            difference_array[first_flight - 1] += seats_to_add
14          
15            # Subtract seats after the end of the booking range
16            # This marks where the booking effect ends
17            if last_flight < n:
18                difference_array[last_flight] -= seats_to_add
19      
20        # Calculate prefix sum to get the actual seat counts for each flight
21        # accumulate() computes running totals from the difference array
22        return list(accumulate(difference_array))
23
1class Solution {
2    public int[] corpFlightBookings(int[][] bookings, int n) {
3        // Initialize result array to store final seat counts for each flight
4        int[] answer = new int[n];
5      
6        // Process each booking using difference array technique
7        for (int[] booking : bookings) {
8            int firstFlight = booking[0];
9            int lastFlight = booking[1];
10            int seatCount = booking[2];
11          
12            // Add seats at the start of the booking range (convert to 0-indexed)
13            answer[firstFlight - 1] += seatCount;
14          
15            // Subtract seats after the end of the booking range
16            // This marks where the booking effect ends
17            if (lastFlight < n) {
18                answer[lastFlight] -= seatCount;
19            }
20        }
21      
22        // Apply prefix sum to get actual seat counts for each flight
23        // The difference array is transformed into the final result
24        for (int i = 1; i < n; i++) {
25            answer[i] += answer[i - 1];
26        }
27      
28        return answer;
29    }
30}
31
1class Solution {
2public:
3    vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
4        // Initialize result array with n flights, all starting with 0 seats
5        vector<int> flightSeats(n);
6      
7        // Apply difference array technique for range updates
8        // For each booking: [firstFlight, lastFlight, seatsToAdd]
9        for (const auto& booking : bookings) {
10            int firstFlight = booking[0];
11            int lastFlight = booking[1];
12            int seatsToAdd = booking[2];
13          
14            // Add seats at the start of the range (convert to 0-indexed)
15            flightSeats[firstFlight - 1] += seatsToAdd;
16          
17            // Subtract seats after the end of the range to mark range boundary
18            // Check bounds to avoid out-of-range access
19            if (lastFlight < n) {
20                flightSeats[lastFlight] -= seatsToAdd;
21            }
22        }
23      
24        // Calculate prefix sum to get actual seat counts for each flight
25        // The difference array is converted to actual values through cumulative sum
26        for (int i = 1; i < n; ++i) {
27            flightSeats[i] += flightSeats[i - 1];
28        }
29      
30        return flightSeats;
31    }
32};
33
1/**
2 * Calculate the total number of seats reserved for each flight
3 * @param bookings - Array of bookings where each booking is [firstFlight, lastFlight, seatsReserved]
4 * @param n - Total number of flights
5 * @returns Array containing the total seats reserved for each flight
6 */
7function corpFlightBookings(bookings: number[][], n: number): number[] {
8    // Initialize result array with n flights, all starting with 0 seats
9    const answer: number[] = new Array(n).fill(0);
10  
11    // Apply difference array technique
12    // Mark the start and end of each booking range
13    for (const [firstFlight, lastFlight, seatsReserved] of bookings) {
14        // Add seats at the start of the booking range (convert to 0-indexed)
15        answer[firstFlight - 1] += seatsReserved;
16      
17        // Subtract seats after the end of the booking range
18        if (lastFlight < n) {
19            answer[lastFlight] -= seatsReserved;
20        }
21    }
22  
23    // Calculate prefix sum to get actual seat counts for each flight
24    for (let i = 1; i < n; i++) {
25        answer[i] += answer[i - 1];
26    }
27  
28    return answer;
29}
30

Time and Space Complexity

The time complexity is O(m + n), where m is the number of bookings and n is the number of flights. The algorithm iterates through all m bookings once to update the difference array, which takes O(m) time. Then, it uses accumulate to compute the prefix sum over n elements, which takes O(n) time. Therefore, the total time complexity is O(m + n).

The space complexity is O(1) if we ignore the space consumption of the answer array. The algorithm only uses the answer array ans to store the result, which is required for the output. No additional auxiliary space proportional to the input size is used beyond this required output array.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Index Confusion Between 1-indexed and 0-indexed

The most common mistake is mishandling the conversion between 1-indexed flight numbers (given in the problem) and 0-indexed array positions (used in implementation).

Pitfall Example:

# WRONG: Forgetting to convert to 0-indexed
difference_array[first_flight] += seats_to_add  # Should be first_flight - 1

# WRONG: Incorrect end boundary
difference_array[last_flight - 1] -= seats_to_add  # Should be last_flight, not last_flight - 1

Correct Approach:

  • Start of range: Use first_flight - 1 (converts 1-indexed to 0-indexed)
  • End of range: Use last_flight (this is already the position AFTER the last flight in 0-indexed terms)

2. Boundary Check Omission

Forgetting to check if last_flight < n before subtracting seats can cause an index out of bounds error.

Pitfall Example:

# WRONG: No boundary check
difference_array[last_flight] -= seats_to_add  # Crashes when last_flight == n

Correct Approach:

if last_flight < n:
    difference_array[last_flight] -= seats_to_add

3. Manual Prefix Sum Implementation Errors

If implementing prefix sum manually instead of using accumulate, off-by-one errors are common.

Pitfall Example:

# WRONG: Starting from index 1 instead of 0
for i in range(1, n):
    difference_array[i] += difference_array[i - 1]

# This misses accumulating the first element properly

Correct Manual Implementation:

# Option 1: Modify in-place starting from index 1
for i in range(1, n):
    difference_array[i] += difference_array[i - 1]
return difference_array

# Option 2: Use a separate result array
result = [difference_array[0]]
for i in range(1, n):
    result.append(result[-1] + difference_array[i])
return result

4. Understanding the Difference Array Logic

A conceptual pitfall is thinking you need to subtract at last_flight - 1 or add at first_flight without the -1 adjustment.

Key Insight:

  • We add seats at the START of the range (index first - 1 in 0-indexed)
  • We subtract seats AFTER the range ends (index last in 0-indexed, which represents position last + 1 in 1-indexed terms)
  • This ensures the prefix sum includes the seats for all flights from first to last inclusive
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which algorithm should you use to find a node that is close to the root of the tree?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More