Facebook Pixel

849. Maximize Distance to Closest Person

Problem Description

You have an array seats representing a row of seats where:

  • seats[i] = 1 means a person is sitting in the i-th seat
  • seats[i] = 0 means the i-th seat is empty
  • The array is 0-indexed

The problem guarantees that there is at least one empty seat and at least one person sitting.

Alex wants to find an empty seat to sit in such that he maximizes the distance to the closest person next to him. Your task is to return this maximum possible distance.

For example, if seats = [1, 0, 0, 0, 1, 0, 1], Alex could sit at index 2, which gives him a distance of 2 from the closest person. This would be the maximum possible distance he could achieve in this arrangement.

The distance is measured as the number of seats between Alex and the nearest person. You need to consider:

  • Empty seats at the beginning (distance from the first person)
  • Empty seats at the end (distance from the last person)
  • Empty seats between two people (distance to the closer person)
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

To maximize Alex's distance from the closest person, we need to consider three possible scenarios for where Alex could sit:

  1. At the beginning of the row: If there are empty seats before the first person, Alex could sit at seat 0. The distance would be equal to the position of the first person.

  2. At the end of the row: If there are empty seats after the last person, Alex could sit at the last seat. The distance would be n - last_person_position - 1.

  3. Between two people: If there's a gap between two people, Alex should sit in the middle of that gap to maximize distance from both. If the gap has length d, sitting in the middle gives a distance of d // 2 to the closest person.

The key insight is that we only need to track:

  • The position of the first person (first)
  • The position of the last person (last)
  • The maximum gap between any two consecutive people (d)

As we traverse the array once, whenever we encounter a person:

  • If it's the first person we've seen, we record their position
  • If we've seen people before, we calculate the gap from the previous person
  • We always update the position of the most recent person we've seen

After the traversal, we have all the information needed to determine the maximum distance: it's the maximum of sitting at the beginning, sitting at the end, or sitting in the middle of the largest gap between two people.

Solution Approach

We implement a single-pass traversal algorithm to find the maximum distance to the closest person.

Variables Used:

  • first: Tracks the position of the first person in the array (initially None)
  • last: Tracks the position of the most recently seen person (initially None)
  • d: Tracks the maximum distance between any two consecutive people (initially 0)

Algorithm Steps:

  1. Traverse the array using enumeration to get both index i and value c:

    for i, c in enumerate(seats):
  2. When we encounter a person (c == 1):

    • Update maximum gap: If last is not None (meaning we've seen a person before), calculate the gap between current person and previous person: d = max(d, i - last)
    • Record first person: If first is None (meaning this is the first person), set first = i
    • Update last person: Always update last = i to track the most recent person's position
  3. Calculate the final result by taking the maximum of three values:

    • first: Distance if Alex sits at seat 0 (beginning)
    • len(seats) - last - 1: Distance if Alex sits at the last seat (end)
    • d // 2: Distance if Alex sits in the middle of the largest gap between two people

The reason we use d // 2 for gaps between people is that Alex would sit in the middle of the gap to maximize distance from both neighbors. For example, if there's a gap of 4 empty seats between two people, sitting in the middle gives a distance of 2 to the closest person.

Time Complexity: O(n) where n is the length of the seats array (single pass)
Space Complexity: O(1) as we only use a constant amount of extra space

Ready to land your dream job?

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

Start Evaluator

Example Walkthrough

Let's walk through the solution with seats = [1, 0, 0, 0, 1, 0, 1]:

Initial State:

  • first = None (haven't seen first person yet)
  • last = None (haven't seen any person yet)
  • d = 0 (no gaps calculated yet)

Traversal:

  1. i = 0, c = 1 (person at seat 0)

    • Since last = None, we don't calculate any gap
    • Since first = None, set first = 0
    • Update last = 0
    • State: first = 0, last = 0, d = 0
  2. i = 1, c = 0 (empty seat)

    • Skip (only process when we find a person)
  3. i = 2, c = 0 (empty seat)

    • Skip
  4. i = 3, c = 0 (empty seat)

    • Skip
  5. i = 4, c = 1 (person at seat 4)

    • Since last = 0, calculate gap: d = max(0, 4 - 0) = 4
    • first remains 0
    • Update last = 4
    • State: first = 0, last = 4, d = 4
  6. i = 5, c = 0 (empty seat)

    • Skip
  7. i = 6, c = 1 (person at seat 6)

    • Since last = 4, calculate gap: d = max(4, 6 - 4) = max(4, 2) = 4
    • first remains 0
    • Update last = 6
    • State: first = 0, last = 6, d = 4

Final Calculation:

  • Distance if sitting at beginning: first = 0 (no empty seats before first person)
  • Distance if sitting at end: 7 - 6 - 1 = 0 (no empty seats after last person)
  • Distance if sitting between people: d // 2 = 4 // 2 = 2

Result: max(0, 0, 2) = 2

Alex should sit at index 2 (middle of the gap between seats 0 and 4), giving him a distance of 2 from the closest person.

Solution Implementation

1class Solution:
2    def maxDistToClosest(self, seats: List[int]) -> int:
3        # Track the first and last occupied seat positions
4        first_occupied = None
5        last_occupied = None
6      
7        # Track the maximum distance between two consecutive occupied seats
8        max_distance_between_occupied = 0
9      
10        # Iterate through all seats to find occupied ones
11        for index, is_occupied in enumerate(seats):
12            if is_occupied:
13                # If we've seen an occupied seat before, calculate distance
14                if last_occupied is not None:
15                    max_distance_between_occupied = max(
16                        max_distance_between_occupied, 
17                        index - last_occupied
18                    )
19              
20                # Record the first occupied seat we encounter
21                if first_occupied is None:
22                    first_occupied = index
23              
24                # Update the most recent occupied seat position
25                last_occupied = index
26      
27        # The maximum distance to the closest person can be:
28        # 1. Distance from start to first occupied seat (edge case)
29        # 2. Distance from last occupied seat to end (edge case)
30        # 3. Half the distance between two occupied seats (middle case)
31        return max(
32            first_occupied,                              # Distance from start
33            len(seats) - last_occupied - 1,             # Distance to end
34            max_distance_between_occupied // 2          # Half of max gap between occupied seats
35        )
36
1class Solution {
2    public int maxDistToClosest(int[] seats) {
3        // Track the first and last occupied seat positions
4        int firstOccupiedIndex = -1;
5        int lastOccupiedIndex = -1;
6      
7        // Track the maximum distance between consecutive occupied seats
8        int maxDistanceBetweenOccupied = 0;
9        int totalSeats = seats.length;
10      
11        // Iterate through all seats to find occupied positions
12        for (int currentIndex = 0; currentIndex < totalSeats; currentIndex++) {
13            if (seats[currentIndex] == 1) {
14                // Calculate distance between consecutive occupied seats
15                if (lastOccupiedIndex != -1) {
16                    int distanceBetweenSeats = currentIndex - lastOccupiedIndex;
17                    maxDistanceBetweenOccupied = Math.max(maxDistanceBetweenOccupied, distanceBetweenSeats);
18                }
19              
20                // Record the first occupied seat
21                if (firstOccupiedIndex == -1) {
22                    firstOccupiedIndex = currentIndex;
23                }
24              
25                // Update the last occupied seat position
26                lastOccupiedIndex = currentIndex;
27            }
28        }
29      
30        // Calculate the maximum distance to the closest person
31        // Consider three cases:
32        // 1. Sitting between two occupied seats (distance / 2)
33        // 2. Sitting at the beginning before the first occupied seat
34        // 3. Sitting at the end after the last occupied seat
35        int distanceFromMiddle = maxDistanceBetweenOccupied / 2;
36        int distanceFromStart = firstOccupiedIndex;
37        int distanceFromEnd = totalSeats - lastOccupiedIndex - 1;
38      
39        return Math.max(distanceFromMiddle, Math.max(distanceFromStart, distanceFromEnd));
40    }
41}
42
1class Solution {
2public:
3    int maxDistToClosest(vector<int>& seats) {
4        // Track the first and last occupied seat positions
5        int firstOccupiedIndex = -1;
6        int lastOccupiedIndex = -1;
7      
8        // Track the maximum distance between consecutive occupied seats
9        int maxDistanceBetweenOccupied = 0;
10        int totalSeats = seats.size();
11      
12        // Iterate through all seats to find occupied positions
13        for (int currentIndex = 0; currentIndex < totalSeats; ++currentIndex) {
14            if (seats[currentIndex] == 1) {
15                // If we've seen an occupied seat before, calculate distance
16                if (lastOccupiedIndex != -1) {
17                    maxDistanceBetweenOccupied = max(maxDistanceBetweenOccupied, 
18                                                     currentIndex - lastOccupiedIndex);
19                }
20              
21                // Record the first occupied seat
22                if (firstOccupiedIndex == -1) {
23                    firstOccupiedIndex = currentIndex;
24                }
25              
26                // Update the last occupied seat position
27                lastOccupiedIndex = currentIndex;
28            }
29        }
30      
31        // Calculate the maximum distance considering three scenarios:
32        // 1. Distance from start to first occupied seat
33        // 2. Distance from last occupied seat to end
34        // 3. Half the distance between any two consecutive occupied seats
35        return max({maxDistanceBetweenOccupied / 2, 
36                    firstOccupiedIndex, 
37                    totalSeats - lastOccupiedIndex - 1});
38    }
39};
40
1/**
2 * Finds the maximum distance to the closest person in a row of seats.
3 * @param seats - Array where 1 represents an occupied seat and 0 represents an empty seat
4 * @returns The maximum distance to the closest person when sitting in an empty seat
5 */
6function maxDistToClosest(seats: number[]): number {
7    // Track the first and last occupied seat positions
8    let firstOccupiedIndex: number = -1;
9    let lastOccupiedIndex: number = -1;
10  
11    // Maximum distance between two consecutive occupied seats
12    let maxDistanceBetweenOccupied: number = 0;
13    const totalSeats: number = seats.length;
14  
15    // Iterate through all seats to find occupied positions
16    for (let currentIndex = 0; currentIndex < totalSeats; currentIndex++) {
17        if (seats[currentIndex] === 1) {
18            // If this is not the first occupied seat, calculate distance from previous occupied seat
19            if (lastOccupiedIndex !== -1) {
20                const distanceBetweenCurrent = currentIndex - lastOccupiedIndex;
21                maxDistanceBetweenOccupied = Math.max(maxDistanceBetweenOccupied, distanceBetweenCurrent);
22            }
23          
24            // Record the first occupied seat position
25            if (firstOccupiedIndex === -1) {
26                firstOccupiedIndex = currentIndex;
27            }
28          
29            // Update the last occupied seat position
30            lastOccupiedIndex = currentIndex;
31        }
32    }
33  
34    // Calculate maximum distance considering three scenarios:
35    // 1. Distance from start to first occupied seat
36    // 2. Distance from last occupied seat to end
37    // 3. Half the distance between any two occupied seats (sitting in the middle)
38    const distanceFromStart: number = firstOccupiedIndex;
39    const distanceFromEnd: number = totalSeats - lastOccupiedIndex - 1;
40    const middleDistance: number = maxDistanceBetweenOccupied >> 1; // Bit shift right by 1 (divide by 2)
41  
42    return Math.max(distanceFromStart, distanceFromEnd, middleDistance);
43}
44

Time and Space Complexity

The time complexity is O(n), where n is the length of the array seats. The algorithm iterates through the array exactly once using the enumerate function, performing constant-time operations (comparisons and assignments) for each element.

The space complexity is O(1). The algorithm only uses a fixed number of variables (first, last, d, i, and c) regardless of the input size, requiring constant extra space.

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

Common Pitfalls

1. Forgetting to Handle Edge Cases (Beginning and End Seats)

Pitfall: A common mistake is only considering gaps between occupied seats and using max_distance // 2 as the final answer, forgetting that sitting at the very first or very last seat might provide a greater distance.

Example of Incorrect Approach:

def maxDistToClosest(self, seats: List[int]) -> int:
    max_gap = 0
    last_person = -1
  
    for i, seat in enumerate(seats):
        if seat == 1:
            if last_person != -1:
                max_gap = max(max_gap, i - last_person)
            last_person = i
  
    return max_gap // 2  # WRONG: Ignores edge seats!

Why it fails: For seats = [1, 0, 0, 0], this would return 0, but the correct answer is 3 (sitting at the last seat).

Solution: Always consider three cases:

  • Distance from seat 0 to the first person
  • Distance from the last seat to the last person
  • Half the maximum gap between any two people

2. Integer Division Confusion for Odd Gaps

Pitfall: Not understanding why we use integer division (//) instead of regular division when calculating max_distance_between_occupied // 2.

Example: If the gap between two people is 5 seats (indices 1 and 7 are occupied, with empty seats at 2,3,4,5,6), Alex should sit at index 4, giving a distance of 2 to the nearest person. Using 5 // 2 = 2 is correct, but some might think we need ceil(5 / 2) = 3.

Why // is correct: When sitting between two people, we want the minimum distance to either neighbor. For a gap of size d:

  • Odd gap (e.g., 5): Sitting in the middle gives distance 2 to both neighbors
  • Even gap (e.g., 4): Sitting at either middle position gives distance 1 to one neighbor and 2 to the other

The floor division naturally gives us the correct minimum distance.

3. Off-by-One Error When Calculating Distance to End

Pitfall: Incorrectly calculating the distance when sitting at the last seat.

Incorrect: len(seats) - last_occupied
Correct: len(seats) - last_occupied - 1

Example: For seats = [1, 0, 0]:

  • Last occupied is at index 0
  • Last seat is at index 2
  • Distance = 2 - 0 = 2 ❌ (This would be counting seats, not gaps)
  • Distance = 2 - 0 - 1 = 1 ❌ (This is also wrong!)
  • Actually: len(seats) - 1 - last_occupied = 3 - 1 - 0 = 2

Better way to think about it: The last index is len(seats) - 1, so the distance from last_occupied to the last seat is (len(seats) - 1) - last_occupied.

Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

A person thinks of a number between 1 and 1000. You may ask any number questions to them, provided that the question can be answered with either "yes" or "no".

What is the minimum number of questions you needed to ask so that you are guaranteed to know the number that the person is thinking?


Recommended Readings

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

Load More