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.

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 Yourselfredirect 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?

#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 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));

`