Note that the problem is to find the largest subarray that fulfills the condition. Realize that if the condition holds for an interval of indices, it holds also for all the intervals included in it. So if we fix one border, we can greedily choose the other border as much away from it as possible.
It's possible to solve this in linear time:
Define ri as the rightmost possible right boundary if you choose element i as the left boundary. We can show that r is monotonous in i, so we can maintain two pointers to i and ri and increment ri as much as possible every time after we increment i by one. Both pointers are incremented a total of O(n) times and we can maintain the range minima / maxima in O(log n) per increment using a heap or binary search tree of the values in the range.
Using a monotonic queue we can maintain the extrema in O(1) and get a total runtime of O(n). Another C++ implementation of the queue can be found here, for example.
Another somewhat less elegant way would be to use a RMQ data structure. It let's you query the min/max in a range in O(1) after O(n log n) preprocessing (O(n) preprocessing is also 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 binary search to find the rightmost right boundary which still fulfills the condition (you can check in O(1) whether it does).
This works because the predicate "range fulfills the condition" is monotonous with regard to inclusion (if a range fulfills it, all ranges included in it also fulfill it).