Thursday, August 31st

 Water Taps

Given the locations and ranges of water taps in a 1-dimensional garden, determine the minimum number of taps required to water the garden

An irrigation sprinkler courtesy of Nevit Dilmen via Wikipedia.  Distributed under the Creative Commons Attribution-Share Alike 3.0 Unported license.  No changes made.

This problem can be solved in a greedy manner by organizing taps based on their reach

First create a vector to store the maximum reaches of taps

int minTaps(int n, vector<int>& ranges) {
vector<int> maxReach(n + 1);
        ...
    }

Then for each tap, determine its left and rightmost reach, minding limits of the garden.  Then, for each starting position, use the maxReach vector and the max() function to store the maximum reach of sprinklers beginning from the give start

    for (int i = 0; i < ranges.size(); i++) {
int start = max(0, i - ranges[i]); //leftmost
int end = min(n, i + ranges[i]); //rightmost
        maxReach[start] = max(maxReach[start], end);
    }

Then initiate the greedy solution by initializing variables to count the number of taps, store the rightmost position reached, and the next endpoint

int taps = 0;
int currEnd = 0;
int nextEnd = 0;

For the meat of the program.  Minding the initiation of the variables above, iterate from i=0 to n.  If i is greater than nextEnd, return -1.  Otherwise, if I is greater than currEnd, increment the number of taps and spade currEnd to nextEnd.  Finally, set nextEnd to the max of itself and its entry in maxReach.  This allows us to select taps based on furthest reach right.

    for (int i = 0; i <= n; i++) {
if (i > nextEnd) {
return -1;
}
if (i > currEnd) {
taps++;
currEnd = nextEnd;
}
nextEnd = max(nextEnd, maxReach[i]);
}

Finally, return the number of taps

    int minTaps(int n, vector<int>& ranges) {
        ...
     return taps;
}

A challenging dynamic programming problem with a sensible greedy approach

Thanks to the Editorial for a clear, concise, and well-commented solution

Comments

Popular posts from this blog

Wednesday, September 20th

Monday, September 11th

Tuesday, September 19th