There are n rooms in a straight line in Geekland State University's hostel. You are given a binary string s of length n, where s[i] = '1' means there is a WiFi router in the i-th room, and s[i] = '0' means there is no WiFi in that room.
- Each WiFi router has a range of x, meaning it can cover up to x rooms to its left and x rooms to its right.
- Given x and s, find whether all rooms are covered by at least one WiFi router.
Examples:
Input: x = 0, s = "010"
Output: false
Explanation: Since the range is 0, so Wifi is only accessible in second room while 1st & 3rd room have no wifi. Therefore answer is false for this test case.Input: x = 1, s = "10010"
Output: true
Explanation:
Index 0: WiFi is available.
Index 1: Since the range of the 0th index is 1, WiFi is available here.
Index 2: Since the range of the 3rd index is 1, WiFi is also available here.
Index 3: WiFi is available.
Index 4: The range of the 3rd index covers this position.
So, all the rooms have WiFi. Therefore, the answer is true.
Table of Content
[Naive Approach] One by One Check Rooms - O(n²) Time and O(1) Space
The approach is to check every position in the string and verify whether it is covered by at least one WiFi router.
For each index i, we iterate through all indices j to find a router (s[j] == '1') such that the distance between them is within the allowed range x (i.e., |i - j| ≤ x). If such a router exists, the position is considered covered. If for any position no such router is found, we immediately return false. If all positions are successfully covered, we return true.
#include <iostream>
#include <string>
using namespace std;
// Function to check if all positions can be covered
bool wifiRange(string s, int x)
{
int n = s.length();
// check every position
for (int i = 0; i < n; i++) {
bool covered = false;
// check all possible WiFi positions
for (int j = 0; j < n; j++) {
// if WiFi exists and can cover position i
if (s[j] == '1' && abs(i - j) <= x) {
covered = true;
break;
}
}
// if any position is not covered → return false
if (!covered) return false;
}
return true;
}
// Driver code
int main()
{
cout << (wifiRange("10010", 1) ? "true" : "false") << endl;
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Function to check if all positions can be covered
int wifiRange(char *s, int x)
{
int n = strlen(s);
// check every position
for (int i = 0; i < n; i++) {
int covered = 0;
// check all possible WiFi positions
for (int j = 0; j < n; j++) {
// if WiFi exists and can cover position i
if (s[j] == '1' && abs(i - j) <= x) {
covered = 1;
break;
}
}
// if any position is not covered → return false
if (!covered) return 0;
}
return 1;
}
// Driver code
int main()
{
printf("%s\n", wifiRange("10010", 1) ? "true" : "false");
return 0;
}
import java.util.*;
class GFG {
// Function to check if all positions can be covered
static boolean wifiRange(String s, int x)
{
int n = s.length();
// check every position
for (int i = 0; i < n; i++) {
boolean covered = false;
// check all possible WiFi positions
for (int j = 0; j < n; j++) {
// if WiFi exists and can cover position i
if (s.charAt(j) == '1' && Math.abs(i - j) <= x) {
covered = true;
break;
}
}
// if any position is not covered → return false
if (!covered) return false;
}
return true;
}
public static void main(String[] args)
{
System.out.println(wifiRange("10010", 1) ? "true" : "false");
}
}
# Function to check if all positions can be covered
def wifiRange(s, x):
n = len(s)
# check every position
for i in range(n):
covered = False
# check all possible WiFi positions
for j in range(n):
# if WiFi exists and can cover position i
if s[j] == '1' and abs(i - j) <= x:
covered = True
break
# if any position is not covered → return false
if not covered:
return False
return True
# Driver code
print("true" if wifiRange("10010", 1) else "false")
using System;
class GFG {
// Function to check if all positions can be covered
static bool wifiRange(string s, int x)
{
int n = s.Length;
// check every position
for (int i = 0; i < n; i++) {
bool covered = false;
// check all possible WiFi positions
for (int j = 0; j < n; j++) {
// if WiFi exists and can cover position i
if (s[j] == '1' && Math.Abs(i - j) <= x) {
covered = true;
break;
}
}
// if any position is not covered → return false
if (!covered) return false;
}
return true;
}
public static void Main()
{
Console.WriteLine(wifiRange("10010", 1) ? "true" : "false");
}
}
// Function to check if all positions can be covered
function wifiRange(s, x)
{
let n = s.length;
// check every position
for (let i = 0; i < n; i++) {
let covered = false;
// check all possible WiFi positions
for (let j = 0; j < n; j++) {
// if WiFi exists and can cover position i
if (s[j] === '1' && Math.abs(i - j) <= x) {
covered = true;
break;
}
}
// if any position is not covered → return false
if (!covered) return false;
}
return true;
}
// Driver code
console.log(wifiRange("10010", 1) ? "true" : "false");
[Better Approach] Using Prefix and Suffix Arrays - O(n) Time and O(n) Space
We can use prefix array and suffix array to preprocess the positions of the nearest wifi in the left and right directions for each room. .
Follow the steps to implement the approach:
- Initialize two arrays left and right of size n with initial values of negative and positive infinity respectively.
- Iterate i from 0 to n-1. If s[i] is equal to '1', set last equal to i and set left[i] equal to last.
- Now iterate from n-1 to 0. If s[i] is equal to '1', set last equal to i. Set right[i] equal to last.
- Iterate through each room i from 0 to n-1.Check if the distance between room i and the nearest wifi in left or right is greater than x.
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// Function to check if all positions
// can be covered by WiFi range
bool wifiRange(string s, int x)
{
int n = s.length();
// left[i] -> nearest wifi index on left
// right[i] -> nearest wifi index on right
vector<int> left(n, -1e9), right(n, 1e9);
int last = -1e9;
// fill nearest left wifi
for (int i = 0; i < n; i++) {
if (s[i] == '1') {
last = i;
}
left[i] = last;
}
last = 1e9;
// fill nearest right wifi
for (int i = n - 1; i >= 0; i--) {
if (s[i] == '1') {
last = i;
}
right[i] = last;
}
// check coverage
for (int i = 0; i < n; i++) {
if (abs(i - left[i]) > x &&
abs(i - right[i]) > x) {
return false;
}
}
return true;
}
// Driver code
int main()
{
cout << (wifiRange("10010", 1) ? "true" : "false") << endl;
return 0;
}
import java.util.*;
class GFG {
// Function to check if all positions can
// be covered by WiFi range
static boolean wifiRange(String s, int x)
{
int n = s.length();
// left[i] -> nearest wifi index on left
// right[i] -> nearest wifi index on right
int[] left = new int[n];
int[] right = new int[n];
Arrays.fill(left, (int)-1e9);
Arrays.fill(right, (int)1e9);
int last = (int)-1e9;
// fill nearest left wifi
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '1') {
last = i;
}
left[i] = last;
}
last = (int)1e9;
// fill nearest right wifi
for (int i = n - 1; i >= 0; i--) {
if (s.charAt(i) == '1') {
last = i;
}
right[i] = last;
}
// check coverage
for (int i = 0; i < n; i++) {
if (Math.abs(i - left[i]) > x && Math.abs(i - right[i]) > x) {
return false;
}
}
return true;
}
public static void main(String[] args)
{
System.out.println(wifiRange("10010", 1) ? "true" : "false");
}
}
# Function to check if all positions can be covered by WiFi range
def wifiRange(s, x):
n = len(s)
# left[i] -> nearest wifi index on left
# right[i] -> nearest wifi index on right
left = [-10**9] * n
right = [10**9] * n
last = -10**9
# fill nearest left wifi
for i in range(n):
if s[i] == '1':
last = i
left[i] = last
last = 10**9
# fill nearest right wifi
for i in range(n - 1, -1, -1):
if s[i] == '1':
last = i
right[i] = last
# check coverage
for i in range(n):
if abs(i - left[i]) > x and abs(i - right[i]) > x:
return False
return True
# Driver code
print("true" if wifiRange("10010", 1) else "false")
using System;
class GFG {
// Function to check if all positions can
// be covered by WiFi range
static bool wifiRange(string s, int x)
{
int n = s.Length;
// left[i] -> nearest wifi index on left
// right[i] -> nearest wifi index on right
int[] left = new int[n];
int[] right = new int[n];
for (int i = 0; i < n; i++) {
left[i] = (int)-1e9;
right[i] = (int)1e9;
}
int last = (int)-1e9;
// fill nearest left wifi
for (int i = 0; i < n; i++) {
if (s[i] == '1') {
last = i;
}
left[i] = last;
}
last = (int)1e9;
// fill nearest right wifi
for (int i = n - 1; i >= 0; i--) {
if (s[i] == '1') {
last = i;
}
right[i] = last;
}
// check coverage
for (int i = 0; i < n; i++) {
if (Math.Abs(i - left[i]) > x && Math.Abs(i - right[i]) > x) {
return false;
}
}
return true;
}
public static void Main()
{
Console.WriteLine(wifiRange("10010", 1) ? "true" : "false");
}
}
// Function to check if all positions can be covered by WiFi range
function wifiRange(s, x)
{
let n = s.length;
// left[i] -> nearest wifi index on left
// right[i] -> nearest wifi index on right
let left = new Array(n).fill(-1e9);
let right = new Array(n).fill(1e9);
let last = -1e9;
// fill nearest left wifi
for (let i = 0; i < n; i++) {
if (s[i] === '1') {
last = i;
}
left[i] = last;
}
last = 1e9;
// fill nearest right wifi
for (let i = n - 1; i >= 0; i--) {
if (s[i] === '1') {
last = i;
}
right[i] = last;
}
// check coverage
for (let i = 0; i < n; i++) {
if (Math.abs(i - left[i]) > x && Math.abs(i - right[i]) > x) {
return false;
}
}
return true;
}
// Driver code
console.log(wifiRange("10010", 1) ? "true" : "false");
Output
true
[Expected Approach] Using Greedy Approach - O(n) Time and O(1) Space
We use a greedy approach by keeping track of the farthest position covered so. Whenever we find a WiFi router,, we extend the coverage range. In the end, we verify whether the entire string is covered.
- Initialize
maxReach = -1 - Traverse the string. If
s[i] == '1', check if it able to able to cover all before it.If gap exists, returnfalse - Update
maxReach = max(maxReach, i + x) - After loop, check
maxReach >= n - 1
#include <iostream>
#include <string>
using namespace std;
// Function to check if all positions can be covered
bool wifiRange(string s, int x) {
int n = s.length();
// Keeps track of the rightmost covered room
int maxReach = -1;
for (int i = 0; i < n; i++) {
if (s[i] == '1') {
// If gap exists between previous
// coverage and current WiFi
if (maxReach < i - x - 1) {
return false;
}
// Update maximum reach
maxReach = max(maxReach, i + x);
}
}
// Check if last position is covered
return maxReach >= n - 1;
}
// Driver code
int main() {
cout << (wifiRange("10010", 1) ? "true" : "false") << endl;
return 0;
}
import java.util.*;
class GFG {
// Function to check if all positions can be covered
static boolean wifiRange(String s, int x) {
int n = s.length();
// Keeps track of the rightmost covered room
int maxReach = -1;
for (int i = 0; i < n; i++) {
if (s.charAt(i) == '1') {
// If gap exists between previous
// coverage and current WiFi
if (maxReach < i - x - 1) {
return false;
}
// Update maximum reach
maxReach = Math.max(maxReach, i + x);
}
}
// Check if last position is covered
return maxReach >= n - 1;
}
public static void main(String[] args) {
System.out.println(wifiRange("10010", 1) ? "true" : "false");
}
}
# Function to check if all positions can be covered
def wifiRange(s, x):
n = len(s)
# Keeps track of the rightmost covered room
maxReach = -1
for i in range(n):
if s[i] == '1':
# If gap exists between previous coverage and current WiFi
if maxReach < i - x - 1:
return False
# Update maximum reach
maxReach = max(maxReach, i + x)
# Check if last position is covered
return maxReach >= n - 1
# Driver code
print("true" if wifiRange("10010", 1) else "false")
using System;
class GFG {
// Function to check if all positions can be covered
static bool wifiRange(string s, int x) {
int n = s.Length;
// Keeps track of the rightmost covered room
int maxReach = -1;
for (int i = 0; i < n; i++) {
if (s[i] == '1') {
// If gap exists between previous coverage and current WiFi
if (maxReach < i - x - 1) {
return false;
}
// Update maximum reach
maxReach = Math.Max(maxReach, i + x);
}
}
// Check if last position is covered
return maxReach >= n - 1;
}
public static void Main() {
Console.WriteLine(wifiRange("10010", 1) ? "true" : "false");
}
}
// Function to check if all positions can be covered
function wifiRange(s, x) {
let n = s.length;
// Keeps track of the rightmost covered room
let maxReach = -1;
for (let i = 0; i < n; i++) {
if (s[i] === '1') {
// If gap exists between previous coverage and current WiFi
if (maxReach < i - x - 1) {
return false;
}
// Update maximum reach
maxReach = Math.max(maxReach, i + x);
}
}
// Check if last position is covered
return maxReach >= n - 1;
}
// Driver code
console.log(wifiRange("10010", 1) ? "true" : "false");
Output
true