Find 0 with Farthest 1s in a Binary Array
Given a string (seats) of 1s and 0s, where 1 represents a filled seat and 0 represents an empty seat in a row. Find an empty seat with maximum distance from an occupied seat. Return the maximum distance.
Examples:
Input: Seats = "1000101"
Output: 2
Explanation: Geek can take 3rd place and have a distance of 2 in left and 2 in right.Input: Seats = "1000"
Output: 3
Explanation: Geek can take the rightmost seat to have a distance of 3.
Table of Content
[Naive Approach] Using Extra Array – O(n) Time and O(n) Space
This approach involves preprocessing the string to the identify the distance of the each empty seat from the nearest left occupied and right seats.
Step by Step Approach
- Traverse the given string and fill closest one distance (in an array leftDist) on left for every 0.
- Traverse again (this time from right to left) and fill closest one distance (in an array rightDist) on left for every 0.
- In the final traversal, find the 0 which has maximum of mins of left and right distances
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int maxDistToClosest(string seats)
{
int n = seats.length();
vector<int> disLeft(n, n), disRight(n, n);
int nearOccu = -n;
// Preprocess distance to left
for (int i = 0; i < n; ++i)
{
if (seats[i] == '1')
{
nearOccu = i;
}
else
{
disLeft[i] = i - nearOccu;
}
}
// Reset nearOccu for next iteration
nearOccu = 2 * n;
// Preprocess distance to right
for (int i = n - 1; i >= 0; --i)
{
if (seats[i] == '1')
{
nearOccu = i;
}
else
{
disRight[i] = nearOccu - i;
}
}
// Calculate maximum distance
int res = 0;
for (int i = 0; i < n; ++i)
{
if (seats[i] == '0')
{
res = max(res, min(disLeft[i], disRight[i]));
}
}
return res;
}
int main()
{
string seats = "1000101";
cout << maxDistToClosest(seats) << endl;
return 0;
}
public class GFG {
public static int maxDistToClosest(String seats)
{
int n = seats.length();
int[] disLeft = new int[n];
int[] disRight = new int[n];
int nearOccu = -n;
// Preprocess distance to left
for (int i = 0; i < n; i++) {
if (seats.charAt(i) == '1') {
nearOccu = i;
}
else {
disLeft[i] = i - nearOccu;
}
}
// Reset nearOccu for next iteration
nearOccu = 2 * n;
// Preprocess distance to right
for (int i = n - 1; i >= 0; i--) {
if (seats.charAt(i) == '1') {
nearOccu = i;
}
else {
disRight[i] = nearOccu - i;
}
}
// Calculate maximum distance
int res = 0;
for (int i = 0; i < n; i++) {
if (seats.charAt(i) == '0') {
res = Math.max(
res,
Math.min(disLeft[i],
disRight[i]));
}
}
return res;
}
// Test the function
public static void main(String[] args)
{
String seats = "1000101";
System.out.println(maxDistToClosest(seats));
}
}
# Function to find the maximum distance to the closest '1' for each '0'
def maxDistToClosest(seats):
n = len(seats)
disLeft = [n] * n
disRight = [n] * n
nearOccu = -n
# Preprocess distance to left
for i in range(n):
if seats[i] == '1':
nearOccu = i
else:
disLeft[i] = i - nearOccu
# Reset nearOccu for the next iteration
nearOccu = 2 * n
# Preprocess distance to right
for i in range(n - 1, -1, -1):
if seats[i] == '1':
nearOccu = i
else:
disRight[i] = nearOccu - i
# Calculate maximum distance
res = 0
for i in range(n):
if seats[i] == '0':
res = max(res, min(disLeft[i], disRight[i]))
return res
# Driver code
seats = "1000101"
print(maxDistToClosest(seats)) # Output the maximum distance
// Function to find the maximum distance to the closest '1' for each '0'
using System;
class Program
{
public static int MaxDistToClosest(string seats)
{
int n = seats.Length;
int[] disLeft = new int[n];
int[] disRight = new int[n];
int nearOccu = -n;
int res = 0;
// Preprocess distance to left
for (int i = 0; i < n; ++i)
{
if (seats[i] == '1')
{
nearOccu = i;
}
else
{
disLeft[i] = i - nearOccu;
}
}
// Reset nearOccu for next iteration
nearOccu = 2 * n;
// Preprocess distance to right
for (int i = n - 1; i >= 0; --i)
{
if (seats[i] == '1')
{
nearOccu = i;
}
else
{
disRight[i] = nearOccu - i;
}
}
// Calculate maximum distance
for (int i = 0; i < n; ++i)
{
if (seats[i] == '0')
{
res = Math.Max(res, Math.Min(disLeft[i], disRight[i]));
}
}
return res;
}
static void Main()
{
string seats = "1000101";
Console.WriteLine(MaxDistToClosest(seats)); // Output: 2
}
}
// Function to find the maximum distance to the closest '1' for each '0'
function maxDistToClosest(seats) {
const n = seats.length;
let disLeft = new Array(n).fill(n);
let disRight = new Array(n).fill(n);
let nearOccu = -n;
let res = 0;
// Preprocess distance to left
for (let i = 0; i < n; ++i) {
if (seats[i] === '1') {
nearOccu = i;
} else {
disLeft[i] = i - nearOccu;
}
}
// Reset nearOccu for the next iteration
nearOccu = 2 * n;
// Preprocess distance to right
for (let i = n - 1; i >= 0; --i) {
if (seats[i] === '1') {
nearOccu = i;
} else {
disRight[i] = nearOccu - i;
}
}
// Calculate maximum distance
for (let i = 0; i < n; ++i) {
if (seats[i] === '0') {
res = Math.max(res, Math.min(disLeft[i], disRight[i]));
}
}
return res;
}
// Driver code
const seats = "1000101";
console.log(maxDistToClosest(seats)); // Output: 2
Output
2
[Expected Approach] Using One variable – O(n) Time and O(1) Space
We need to mainly find length of the longest subarray with 0s and place the Geek at the mid of it. So we traverse the array and keep track of empty 0s. If half of the current count is more than the current result, we update the result. One corner case that we need to handle is the case when we have 0s in the beginning and then a 1. We explicitly handle it by initializing result as -1 and then updating the result as count of 0s at the beginning.
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
using namespace std;
int maxDistToClosest(string seats)
{
// Initialize the maximum distance to -1
int res = -1;
// Initialize a variable to count consecutive empty
// seats
int emptyCnt = 0;
// Iterate through the binary string 'seats'
for (int i = 0; i < seats.length(); ++i)
{
if (seats[i] == '0')
{
// Increment the count for consecutive empty
// seats
emptyCnt++;
}
else if (seats[i] == '1' && res == -1)
{
// Update 'res' with
// 'emptyCnt' if it's the first
// occupied seat
res = emptyCnt;
// Reset the count of consecutive empty seats
emptyCnt = 0;
}
else
{
// Update 'res' with half of
// 'emptyCnt' if not the first
// occupied seat
res = max(res, static_cast<int>(ceil(emptyCnt / 2.0)));
// Reset the count of consecutive empty seats
emptyCnt = 0;
}
}
// Update 'res' one more time after the loop
// for any consecutive empty seats at the end
res = max(res, emptyCnt);
return res;
}
// Driver Code
int main()
{
string seats = "1000101";
cout << maxDistToClosest(seats) << endl;
return 0;
}
// Java implementation:
public class Main {
public static int maxDistToClosest(String seats)
{
// Initialize the maximum distance to -1
int res = -1;
// Initialize a variable to count consecutive empty
// seats
int emptyCnt = 0;
// Iterate through the binary string 'seats'
for (int i = 0; i < seats.length(); ++i) {
if (seats.charAt(i) == '0') {
// Increment the count for consecutive empty
// seats
emptyCnt++;
}
else if (seats.charAt(i) == '1'
&& res == -1) {
// Update 'res' with
// 'emptyCnt' if it's the first
// occupied seat
// puipui
res = emptyCnt;
// Reset the count of consecutive empty
// seats
emptyCnt = 0;
}
else {
// Update 'res' with half of
// 'emptyCnt' if not the first
// occupied seat
res = Math.max(
res,
(int)Math.ceil(emptyCnt
/ 2.0));
// Reset the count of consecutive empty
// seats
emptyCnt = 0;
}
}
// Update 'res' one more time after the
// loop for any consecutive empty seats at the end
res
= Math.max(res, emptyCnt);
return res;
}
public static void main(String[] args)
{
String seats = "1000101";
// Calling and printing the result
System.out.println(maxDistToClosest(seats));
}
}
import math
def maxDistToClosest(seats):
# Initialize the maximum distance to -1
res = -1
# Initialize a variable to count consecutive empty seats
emptyCnt = 0
# Iterate through the binary string 'seats'
for i in range(len(seats)):
if seats[i] == '0':
# Increment the count for consecutive empty seats
emptyCnt += 1
elif seats[i] == '1' and res == -1:
# Update 'res' with 'emptyCnt' if it's the first occupied seat
res = emptyCnt
# Reset the count of consecutive empty seats
emptyCnt = 0
else:
# Update 'res' with half of 'emptyCnt' if not the first occupied seat
res = max(res, math.ceil(
emptyCnt / 2))
# Reset the count of consecutive empty seats
emptyCnt = 0
# Update 'res' one more time after the loop
# for any consecutive empty seats at the end
res = max(res, emptyCnt)
return res
# Driver code
seats = '1000101'
# Calling and printing the result
print(maxDistToClosest(seats))
using System;
public class GFG {
public static int MaxDistToClosest(string seats)
{
// Initialize the maximum distance to -1
int res = -1;
// Initialize a variable to count consecutive empty
// seats
int emptyCnt = 0;
// Iterate through the binary string 'seats'
for (int i = 0; i < seats.Length; ++i) {
if (seats[i] == '0') {
// Increment the count for consecutive empty
// seats
emptyCnt++;
}
else if (seats[i] == '1' && res == -1) {
// Update 'res' with
// 'emptyCnt' if it's the first
// occupied seat
res = emptyCnt;
// Reset the count of consecutive empty
// seats
emptyCnt = 0;
}
else {
// Update 'res' with half of
// 'emptyCnt' if not the first
// occupied seat
res = Math.Max(
res,
(int)Math.Ceiling(emptyCnt
/ 2.0));
// Reset the count of consecutive empty
// seats
emptyCnt = 0;
}
}
// Update 'res' one more time after the loop
// for any consecutive empty seats at the end
res
= Math.Max(res, emptyCnt);
return res;
}
public static void Main(string[] args)
{
string seats = "1000101";
// Calling and printing the result
Console.WriteLine(MaxDistToClosest(seats));
}
}
function maxDistToClosest(seats)
{
// Initialize the maximum distance to -1
let res = -1;
// Initialize a variable to count
// consecutive empty seats
let emptyCnt = 0;
// Iterate through the string 'seats'
for (let i = 0; i < seats.length; ++i) {
if (seats[i] === "0") {
// Increment the count for consecutive
// empty seats
emptyCnt++;
}
else if (seats[i] === "1" && res === -1) {
// Update 'res' with
// 'emptyCnt' if it's the first
// occupied seat
res = emptyCnt;
// Reset the count of consecutive empty seats
emptyCnt = 0;
}
else {
// Update 'res' with half of
// 'emptyCnt' if not the
// first occupied seat
res = Math.max(
res,
Math.ceil(emptyCnt / 2));
// Reset the count of consecutive empty seats
emptyCnt = 0;
}
}
// Update 'res' one more time after the
// loop for any consecutive empty seats at the end
res
= Math.max(res, emptyCnt);
return res;
}
// Driver Code
const seats = "1000101";
// Calling and printing the result
console.log(maxDistToClosest(seats));
Output
2