Minimum Workers to Cover All Hours

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.

Try It Yourself
redirect icon

[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 <iostream>
#include <vector>
#include <algorithm>
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<int>& 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<int> 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 men

if __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));

Output
1
Comment