Maximize Distance to Closest Person
MedPrompt
You are given an array representing a row of seats where seats[i] = 1 represents a person sitting in the ith seat, and seats[i] = 0 represents that the ith seat is empty (0-indexed).
There is at least one empty seat, and at least one person sitting.
Alex wants to sit in the seat such that the distance between him and the closest person to him is maximized.
Return that maximum distance to the closest person.
Example 1:
Input: seats = [1,0,0,0,1,0,1]
Output: 2
Explanation:
If Alex sits in the second open seat (i.e. seats[2]), then the closest person has distance 2.
If Alex sits in any other open seat, the closest person has distance 1.
Thus, the maximum distance to the closest person is 2.Example 2:
Input: seats = [1,0,0,0]
Output: 3
Explanation:
If Alex sits in the last seat (i.e. seats[3]), the closest person is 3 seats away.
This is the maximum distance possible, so the answer is 3.Example 3:
Input: seats = [0,1]
Output: 1
Constraints:
2 <= seats.length <= 2 * 104seats[i]is0or1.- At least one seat is empty.
- At least one seat is occupied.
Approaches
3 approaches with complexity analysis and trade-offs.
This approach involves iterating through every empty seat and, for each one, calculating the distance to the nearest person on the left and the nearest person on the right. The minimum of these two distances is the "distance to the closest person" for that specific empty seat. We keep track of the maximum such distance found across all empty seats.
Algorithm
- Initialize
maxDistanceto 0. - Iterate through the
seatsarray with an indexifrom 0 ton-1. - If
seats[i]is 0 (an empty seat):- Find the distance to the nearest person on the left,
leftDist. Search backwards fromi-1to 0. If no person is found,leftDistis effectively infinite. - Find the distance to the nearest person on the right,
rightDist. Search forwards fromi+1ton-1. If no person is found,rightDistis effectively infinite. - The distance for the current empty seat
iismin(leftDist, rightDist). - Update
maxDistance = max(maxDistance, min(leftDist, rightDist)).
- Find the distance to the nearest person on the left,
- After checking all seats, return
maxDistance.
Walkthrough
We can solve this problem by checking every possible empty seat. For each empty seat, we need to determine the distance to the closest person. This involves two sub-problems: finding the closest person to the left and finding the closest person to the right. We can do this by scanning leftwards and rightwards from the current empty seat. The smaller of these two distances is the score for that seat. We then iterate through all empty seats, calculate their scores, and return the maximum score found.
class Solution { public int maxDistToClosest(int[] seats) { int n = seats.length; int maxDistance = 0; for (int i = 0; i < n; i++) { if (seats[i] == 0) { // Find closest person to the left int leftDist = n; // Initialize with a large value for (int j = i - 1; j >= 0; j--) { if (seats[j] == 1) { leftDist = i - j; break; } } // Find closest person to the right int rightDist = n; // Initialize with a large value for (int j = i + 1; j < n; j++) { if (seats[j] == 1) { rightDist = j - i; break; } } int currentMinDist = Math.min(leftDist, rightDist); maxDistance = Math.max(maxDistance, currentMinDist); } } return maxDistance; }}Complexity
Time
O(N^2), where N is the number of seats. For each of the O(N) empty seats, we might scan the entire array in the worst case to find the nearest left and right person.
Space
O(1), as we only use a few variables to store distances and indices.
Trade-offs
Pros
Simple to understand and implement.
Requires no extra space.
Cons
Highly inefficient for large inputs due to the O(N^2) time complexity.
This approach improves upon the brute-force method by pre-calculating the distances to the nearest person on the left and right for every seat. We use two auxiliary arrays for this purpose, which allows us to find the answer in a linear number of passes.
Algorithm
- Create an integer array
leftof sizen. - Initialize a distance variable
distto a large value (e.g.,n). - Iterate from
i = 0ton-1:- If
seats[i] == 1, resetdist = 0. - Else, increment
dist. - Set
left[i] = dist.
- If
- Create an integer array
rightof sizen. - Reset
distto a large value. - Iterate from
i = n-1down to0:- If
seats[i] == 1, resetdist = 0. - Else, increment
dist. - Set
right[i] = dist.
- If
- Initialize
max_dist = 0. - Iterate from
i = 0ton-1:- If
seats[i] == 0, calculatecurrent_dist = min(left[i], right[i]). - Update
max_dist = max(max_dist, current_dist).
- If
- Return
max_dist.
Walkthrough
Instead of repeatedly scanning for the nearest person for each empty seat, we can precompute this information. We use two passes and two auxiliary arrays, left and right.
- Left Pass: We create an array
leftwhereleft[i]stores the distance from seatito the nearest person on its left. We populate this by iterating from left to right. Ifseats[i]has a person,left[i]is 0. Otherwise,left[i]isleft[i-1] + 1. - Right Pass: Similarly, we create an array
rightwhereright[i]stores the distance to the nearest person on its right. We populate this by iterating from right to left. - Final Pass: With
leftandrightarrays computed, we iterate through the seats one last time. For each empty seati, the distance to the closest person is simplymin(left[i], right[i]). We find the maximum of these minimums over all empty seats.
class Solution { public int maxDistToClosest(int[] seats) { int n = seats.length; int[] left = new int[n]; int[] right = new int[n]; // Fill left array int dist = n; // Represents infinity for (int i = 0; i < n; i++) { if (seats[i] == 1) { dist = 0; } else { dist++; } left[i] = dist; } // Fill right array dist = n; // Represents infinity for (int i = n - 1; i >= 0; i--) { if (seats[i] == 1) { dist = 0; } else { dist++; } right[i] = dist; } // Find the maximum of the minimums int maxDistance = 0; for (int i = 0; i < n; i++) { if (seats[i] == 0) { maxDistance = Math.max(maxDistance, Math.min(left[i], right[i])); } } return maxDistance; }}Complexity
Time
O(N). We perform three separate passes over the array (one for `left`, one for `right`, and one for the final calculation), each taking O(N) time. This simplifies to O(N).
Space
O(N), as we use two auxiliary arrays, `left` and `right`, each of size N.
Trade-offs
Pros
Much faster than the brute-force approach with a linear time complexity.
The logic is still relatively straightforward, breaking the problem down into smaller, manageable passes.
Cons
Requires extra space proportional to the input size, which might be a concern for very large inputs.
The most efficient approach solves the problem in a single pass with constant extra space. The key insight is that the maximum distance can only occur in one of three scenarios: an empty block of seats at the beginning, an empty block at the end, or an empty block between two people. We can calculate the maximum distance for each of these cases as we iterate through the array.
Algorithm
- Initialize
max_dist = 0andlast_person_index = -1. - Loop through each seat
ifrom0ton-1. - If
seats[i] == 1:- If
last_person_index == -1(this is the first person found), the maximum distance isi(for sitting atseats[0]). - Else, there is a gap of empty seats between
last_person_indexandi. The best place to sit is in the middle, at a distance of(i - last_person_index) / 2from either person. Updatemax_distwith this value if it's larger. - Update
last_person_index = i.
- If
- After the loop, handle the case of trailing empty seats. The distance from the end of the row to the last person is
n - 1 - last_person_index. Updatemax_distwith this value if it's larger. - Return
max_dist.
Walkthrough
We can optimize to a single pass by realizing that the problem is about finding the largest gap of empty seats. We can iterate through the seats, keeping track of the index of the last person we've seen (lastPersonIndex).
-
Gaps between people: When we are at index
iand find a person (seats[i] == 1), and we have seen a person before atlastPersonIndex, the number of empty seats between them isi - lastPersonIndex - 1. The best place to sit in this gap is in the middle, which gives a maximum distance of(i - lastPersonIndex) / 2to the nearest person. We update our global maximum distance with this value. -
Leading empty seats: If we find the first person at index
i, it means seats0toi-1were empty. The best place to sit is at index0, giving a distance ofi. This is a special case we handle when we find the very first person. -
Trailing empty seats: After the loop finishes, we need to account for any empty seats at the end of the row. The distance from the last person at
lastPersonIndexto the end of the row (n-1) isn - 1 - lastPersonIndex. This is another potential maximum.
By tracking lastPersonIndex and updating the max distance as we find each person, we can solve the problem in one pass.
class Solution { public int maxDistToClosest(int[] seats) { int n = seats.length; int maxDistance = 0; int lastPersonIndex = -1; for (int i = 0; i < n; i++) { if (seats[i] == 1) { if (lastPersonIndex == -1) { // Case: leading zeros. Alex sits at index 0. maxDistance = i; } else { // Case: zeros between two people. Alex sits in the middle. maxDistance = Math.max(maxDistance, (i - lastPersonIndex) / 2); } lastPersonIndex = i; } } // Case: trailing zeros. Alex sits at the last seat. if (lastPersonIndex != n - 1) { maxDistance = Math.max(maxDistance, n - 1 - lastPersonIndex); } return maxDistance; }}Complexity
Time
O(N), as we iterate through the array only once.
Space
O(1), as we only use a few variables to keep track of the last person's index and the maximum distance.
Trade-offs
Pros
Optimal time complexity of O(N).
Optimal space complexity of O(1).
Cons
The logic can be slightly more complex to reason about initially, as it combines multiple cases (leading, middle, and trailing gaps) into a single pass.
Solutions
Solution
class Solution {public int maxDistToClosest(int[] seats) { int first = -1, last = -1; int d = 0, n = seats.length; for (int i = 0; i < n; ++i) { if (seats[i] == 1) { if (last != -1) { d = Math.max(d, i - last); } if (first == -1) { first = i; } last = i; } } return Math.max(d / 2, Math.max(first, n - last - 1)); }}class Solution {public: int maxDistToClosest(vector<int> &seats) { int first = -1, last = -1; int d = 0, n = seats.size(); for (int i = 0; i < n; ++i) { if (seats[i] == 1) { if (last != -1) { d = max(d, i - last); } if (first == -1) { first = i; } last = i; } } return max({d / 2, max(first, n - last - 1)}); }};class Solution: def maxDistToClosest(self, seats: List[int]) -> int: first = last = None d = 0 for i, c in enumerate(seats): if c: if last is not None: d = max(d, i - last) if first is None: first = i last = i return max(first, len(seats) - last - 1, d // 2)Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.