Note that the problem is to find the largest subarray that fulfills the condition. Understand that if a condition is satisfied for an index interval, it is also satisfied for all intervals included in it. Therefore, if we correct one border, we can eagerly choose another border as far as possible from it.
This can be solved in linear time:
Define r i as the rightmost edge if you select the i element as the left border. We can show that r is monotonic in i, so we can maintain two pointers to i and r i and increase r i as much as possible each time after we increase i by one. Both pointers increase in total O (n) times, and we can maintain the minimum / maximum values ββof the range in O (log n) for each increment, using a heap or binary search tree for values ββin the range.
Using a monotone queue, we can maintain extrema in O (1) and get the total execution time of O (n). Another C ++ implementation for the queue can be found here , for example.
Another less elegant way would be to use the RMQ data structure . This allows you to request min / max in a range in O (1) after O (n log n) preprocessing (O (n) preprocessing is possible, but complicated and unnecessary here, since the rest of the algorithm is not linear time).
Now fix the left border (there are n possibilities). Use a binary search to find the far right edge that still satisfies the condition (you can check O (1) if that does).
This works because the predicate "range satisfies the condition" is monotonic with respect to inclusion (if the range satisfies it, all ranges included in it also fulfill it).
Niklas B.
source share