https://leetcode.com/problems/maximize-distance-to-closest-person/
X. https://leetcode.com/problems/maximize-distance-to-closest-person/discuss/137912/C%2B%2BJava-1-Pass-Solution
Approach #3: Group by Zero [Accepted]
https://leetcode.com/problems/maximize-distance-to-closest-person/discuss/155564/Clean-One-Pass-Two-Pointers-Java-Solution
In a row of
seats
, 1
represents a person sitting in that seat, and 0
represents that the seat is empty.
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 closest person.
Example 1:
Input: [1,0,0,0,1,0,1] Output: 2 Explanation: If Alex sits in the second open seat (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.
Count the numbers of continuous zeros in the prefix,
Count the numbers of continuous zeros in middle,
Count the numbers of continuous zeros in the suffix,
res = max(res, zeros)
Count the numbers of continuous zeros in middle,
res = max(res, (zeros + 1) / 2)
Count the numbers of continuous zeros in the suffix,
res = max(res, zeros)
In a group of
K
adjacent empty seats between two people, the answer is (K+1) / 2
.
Algorithm
For each group of
K
empty seats between two people, we can take into account the candidate answer (K+1) / 2
.
For groups of empty seats between the edge of the row and one other person, the answer is
K
, and we should take into account those answers too.
public int maxDistToClosest(int[] seats) {
int N = seats.length;
int K = 0; // current longest group of empty seats
int ans = 0;
for (int i = 0; i < N; ++i) {
if (seats[i] == 1) {
K = 0;
} else {
K++;
ans = Math.max(ans, (K + 1) / 2);
}
}
for (int i = 0; i < N; ++i)
if (seats[i] == 1) {
ans = Math.max(ans, i);
break;
}
for (int i = N - 1; i >= 0; --i)
if (seats[i] == 1) {
ans = Math.max(ans, N - 1 - i);
break;
}
return ans;
}
https://leetcode.com/problems/maximize-distance-to-closest-person/discuss/155564/Clean-One-Pass-Two-Pointers-Java-Solution
Use two pointers.
- If the current value is "0", keep going forward.
- Left pointer points to the position of left "1" and right pointer points to the position of right "1". Keep updating two pointers and calculate the max distance.
- Be careful of two situations: seats[0] is 0 and seats[len - 1] is 0. Just check them and get the final answer. Ex: 00101000.
public int maxDistToClosest(int[] seats) {
int left = -1, maxDis = 0;
int len = seats.length;
for (int i = 0; i < len; i++) {
if (seats[i] == 0) continue;
if (left == -1) {
maxDis = Math.max(maxDis, i);
} else {
maxDis = Math.max(maxDis, (i - left) / 2);
}
left = i;
}
if (seats[len - 1] == 0) {
maxDis = Math.max(maxDis, len - 1 - left);
}
return maxDis;
}
Approach #2: Two Pointer [Accepted]
As we iterate through seats, we'll update the closest person sitting to our left, and closest person sitting to our right.
Algorithm
Keep track of prev
, the filled seat at or to the left of i
, and future
, the filled seat at or to the right of i
.
Then at seat i
, the closest person is min(i - prev, future - i)
, with one exception. i - prev
should be considered infinite if there is no person to the left of seat i
, and similarly future - i
is infinite if there is no one to the right of seat i
.
public int maxDistToClosest(int[] seats) {
int N = seats.length;
int prev = -1, future = 0;
int ans = 0;
for (int i = 0; i < N; ++i) {
if (seats[i] == 1) {
prev = i;
} else {
while (future < N && seats[future] == 0 || future < i)
future++;
int left = prev == -1 ? N : i - prev;
int right = future == N ? N : future - i;
ans = Math.max(ans, Math.min(left, right));
}
}
return ans;
}
X.
Approach #1: Next Array [Accepted]
Let left[i]
be the distance from seat i
to the closest person sitting to the left of i
. Similarly, let right[i]
be the distance to the closest person sitting to the right of i
. This is motivated by the idea that the closest person in seat i
sits a distance min(left[i], right[i])
away.
Algorithm
To construct left[i]
, notice it is either left[i-1] + 1
if the seat is empty, or 0
if it is full. right[i]
is constructed in a similar way.
public int maxDistToClosest(int[] seats) {
int N = seats.length;
int[] left = new int[N], right = new int[N];
Arrays.fill(left, N);
Arrays.fill(right, N);
for (int i = 0; i < N; ++i) {
if (seats[i] == 1)
left[i] = 0;
else if (i > 0)
left[i] = left[i - 1] + 1;
}
for (int i = N - 1; i >= 0; --i) {
if (seats[i] == 1)
right[i] = 0;
else if (i < N - 1)
right[i] = right[i + 1] + 1;
}
int ans = 0;
for (int i = 0; i < N; ++i)
if (seats[i] == 0)
ans = Math.max(ans, Math.min(left[i], right[i]));
return ans;
}