See the original problem on HackerRank.
Solutions
This is a classical greedy interval coverage problem that can be solved in a few ways. The first solution consists in sorting the positions, then walking left-to-right and for each uncovered position, placing the transmitter as far right as possible while still covering it, then skipping everything the transmitter reaches. This solution is \(O(N \cdot logN)\) due to sorting. To search the rightmost position can be done either linearly or using a binary search, since the array is sorted. This is a C++ implementation of the latter approach:
|
|
In essence, each iteration searches for the rightmost house that can still cover the current one. If the next house is too far from the current house (e.g. x[i+1] - x[i] > k), then the current house must be covered by a radio placed on itself. Otherwise, the current house is covered by the rightmost house whose range still includes it. upper_bound binary searches for the first house whose value is greater than the given one.
Using iterators directly:
|
|
To avoid sorting and binary searching, we can allocate a fixed‑size array (since the domain is limited to \(10^5\)) to track all house positions and then scan this array left to right to determine the transmitter for each house. However, because this position array is “dense”, it also includes indices where no houses exist. As a result, we can’t jump directly to the next house and must find it linearly.
Here is a possible implementation:
|
|
A slight optimization consists in iterating backwards from limit to i in the inner loop. Changing this:
|
|
to this:
|
|
This avoids scanning the entire range in the best case.
Note also that we can replace the array of bools with a bitset:
|
|
This solution is linear in time and constant in space (since the domain size is fixed). However, the main loop visits empty positions one-by-one between coverage zones. If houses are very sparse (e.g. houses at 0 and 100000 with k = 1), we’d step through ~100'000 empty cells.