Minimum Workers to Cover All Hours (original) (raw)
Last Updated : 5 Sep, 2025
Given an array **arr[] of size n, where each element arr[i] denotes the range of working hours a person at position i can cover.
- A person at index i can work and cover the time interval [i - arr[i], i + arr[i]].
- If arr[i] = -1, the person is unavailable and cannot cover any time.
Find the minimum number of people required to cover the entire interval **[0, n – 1]. If it is not possible, return -1.
**Examples:
**Input: arr[] = [1, 2, 1, 0]
**Output: 1
**Explanation: The person at index 1 can cover the interval [-1, 3]. After adjusting to valid bounds, this becomes [0, 3], which fully covers the entire working day 0 to n -1. Therefore, only 1 person is required to cover the whole day.**Input: arr[] = [0, 1, 0, -1]
**Output: -1
**Explanation: Person at index 0 covers [0, 0].
Person at index 1 covers [0, 2].
Person at index 2 covers [2, 2].
Since the last hour cannot be covered by any person, it is impossible to cover the full working day.
[Approach] Using Greedy and Sorting - O(n log(n)) Time and O(n) Space
The idea is to always pick the worker who extends coverage the farthest when the current coverage ends. The problem is to cover the full timeline [0 … n-1] using workers’ ranges. Each worker at index i can cover [i - arr[i], i + arr[i]]. We need the minimum number of workers so that all hours are covered without gaps. This reduces to a minimum interval covering problem.
**How it works?
- We need to cover the full timeline [0 … n-1] using the fewest intervals.
- Each worker gives an interval [i - arr[i], i + arr[i]].
- At each step, we track the **current coverage (maxi).
- The next chosen interval must **start at or before maxi + 1.
- If no such interval exists, coverage is impossible.
- Among valid intervals, pick the one with the **farthest right endpoint to maximize future coverage. C++ `
#include #include #include using namespace std;
// comparator function for sorting bool cmp(const pair<int, int>& a, const pair<int, int>& b) { if (a.first == b.first) return a.second > b.second; return a.first < b.first; }
int minMen(vector& arr) { int n = arr.size(); vector<pair<int, int>> range;
// Build intervals [i - arr[i], i + arr[i]] for each valid worker
for (int i = 0; i < n; i++) {
if (arr[i] != -1) {
int left = max(0, i - arr[i]);
int right = min(n - 1, i + arr[i]);
range.push_back({left, right});
}
}// No workers available if (range.empty()) return -1;
// Sort by left bound; if same, prefer
// the one with farther right
sort(range.begin(), range.end(), cmp);
int men = 0, i = 0, maxi = -1;
while (maxi < n - 1) {
// No more intervals
if (i >= (int)range.size()) return -1;
// Gap detected, cannot cover
if (range[i].first > maxi + 1) return -1;
int best = maxi;
// Extend coverage as far as possible with
// current overlapping intervals
while (i < (int)range.size() && range[i].first <= maxi + 1) {
best = max(best, range[i].second);
i++;
}
men++;
maxi = best;
}
return men;}
int main() { vector arr = {1, 2, 1, 0}; cout << minMen(arr) << endl; return 0; }
Java
import java.util.ArrayList; import java.util.List;
public class GFG { static int minMen(int[] arr) { int n = arr.length; List<int[]> range = new ArrayList<>();
// Build intervals [i - arr[i], i + arr[i]]
// for each valid worker
for (int i = 0; i < n; i++) {
if (arr[i] != -1) {
int left = Math.max(0, i - arr[i]);
int right = Math.min(n - 1, i + arr[i]);
range.add(new int[]{left, right});
}
}
// No workers available
if (range.isEmpty()) return -1;
// Sort by left bound; if same,
// prefer the one with farther right
range.sort((a, b) -> {
if (a[0] == b[0]) return Integer.compare(b[1], a[1]);
return Integer.compare(a[0], b[0]);
});
int men = 0, i = 0, maxi = -1;
while (maxi < n - 1) {
// No more intervals
if (i >= range.size()) return -1;
// Gap detected, cannot cover
if (range.get(i)[0] > maxi + 1) return -1;
int best = maxi;
// Extend coverage as far as possible
// with current overlapping intervals
while (i < range.size() && range.get(i)[0] <= maxi + 1) {
best = Math.max(best, range.get(i)[1]);
i++;
}
men++;
maxi = best;
}
return men;
}
public static void main(String[] args) {
int[] arr = {1, 2, 1, 0};
System.out.println(minMen(arr));
}}
Python
def minMen(arr): n = len(arr) ranges = []
# Build intervals [i - arr[i], i + arr[i]] for each valid worker
for i in range(n):
if arr[i] != -1:
left = max(0, i - arr[i])
right = min(n - 1, i + arr[i])
ranges.append([left, right])
# No workers available
if not ranges:
return -1
# Sort by left bound; if same, prefer the one with farther right
ranges.sort(key=lambda x: (x[0], -x[1]))
men, i, maxi = 0, 0, -1
while maxi < n - 1:
# No more intervals
if i >= len(ranges):
return -1
# Gap detected, cannot cover
if ranges[i][0] > maxi + 1:
return -1
best = maxi
# Extend coverage as far as possible
# with current overlapping intervals
while i < len(ranges) and ranges[i][0] <= maxi + 1:
best = max(best, ranges[i][1])
i += 1
men += 1
maxi = best
return menif name=="main": arr = [1, 2, 1, 0] print(minMen(arr))
C#
using System; using System.Collections.Generic;
class GFG { static int minMen(int[] arr) { int n = arr.Length; List<int[]> range = new List<int[]>();
// Build intervals [i - arr[i], i + arr[i]] for each valid worker
for (int i = 0; i < n; i++) {
if (arr[i] != -1) {
int left = Math.Max(0, i - arr[i]);
int right = Math.Min(n - 1, i + arr[i]);
range.Add(new int[] { left, right });
}
}
// No workers available
if (range.Count == 0) return -1;
// Sort by left bound; if same, prefer the one with farther right
range.Sort((a, b) => {
if (a[0] == b[0]) return b[1].CompareTo(a[1]);
return a[0].CompareTo(b[0]);
});
int men = 0, idx = 0, maxi = -1;
while (maxi < n - 1) {
// No more intervals
if (idx >= range.Count) return -1;
// Gap detected, cannot cover
if (range[idx][0] > maxi + 1) return -1;
int best = maxi;
// Extend coverage as far as
// possible with current overlapping intervals
while (idx < range.Count && range[idx][0] <= maxi + 1) {
best = Math.Max(best, range[idx][1]);
idx++;
}
men++;
maxi = best;
}
return men;
}
static void Main() {
int[] arr = { 1, 2, 1, 0 };
Console.WriteLine(minMen(arr));
}}
JavaScript
function minMen(arr) { const n = arr.length; let ranges = [];
// Build intervals [i - arr[i], i + arr[i]] for each valid worker
for (let i = 0; i < n; i++) {
if (arr[i] !== -1) {
let left = Math.max(0, i - arr[i]);
let right = Math.min(n - 1, i + arr[i]);
ranges.push([left, right]);
}
}
// No workers available
if (ranges.length === 0) return -1;
// Sort by left bound; if same, prefer the one with farther right
ranges.sort((a, b) => {
if (a[0] === b[0]) return b[1] - a[1];
return a[0] - b[0];
});
let men = 0, i = 0, maxi = -1;
while (maxi < n - 1) {
// No more intervals
if (i >= ranges.length) return -1;
// Gap detected, cannot cover
if (ranges[i][0] > maxi + 1) return -1;
let best = maxi;
// Extend coverage as far as possible
// with current overlapping intervals
while (i < ranges.length && ranges[i][0] <= maxi + 1) {
best = Math.max(best, ranges[i][1]);
i++;
}
men++;
maxi = best;
}
return men;} // Driver Code let arr = [1, 2, 1, 0]; console.log(minMen(arr));
`