Q:

What is maximum water colledted between two histograms?

I recently came across this problem:

You are given height of n histograms each of width 1. You have to choose any two histograms such that if it starts raining and all other histograms(except the two you have selected) are removed, then the water collected between the two histograms is maximised.

Input:
9
3 2 5 9 7 8 1 4 6
Output:
25

Between third and last histogram.
This is a variant of Trapping rain water problem.
I tried two solutions but both had worst case complexity of N^2. How can we optimise further.

Sol1: Brute force for every pair.
int maxWaterCollected(vector<int> hist, int n) {
    int ans = 0;
    for (int i= 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            ans = max(ans, min(hist[i], hist[j]) * (j - i - 1));
        }
    }

    return ans;
}

Sol2: Keep a sequence of histograms in increasing order of height. For every histogram, find its best histogram in this sequence. now, if all histograms are in increasing order then this solution also becomes N^2.
int maxWaterCollected(vector<int> hist, int n) {
    vector< pair<int, int> > increasingSeq(1, make_pair(hist[0], 0)); // initialised with 1st element.
    int ans = 0;
    for (int i = 1; i < n; i++) {
        // compute best result from current increasing sequence
        for (int j = 0; j < increasingSeq.size(); j++) {
            ans = max(ans, min(hist[i], increasingSeq[j].first) * (i - increasingSeq[j].second - 1));
        }

        // add this histogram to sequence
        if (hist[i] > increasingSeq.back().first) {
            increasingSeq.push_back(make_pair(hist[i], i));
        }
    }

    return ans;
}

A:

Jarod42 has the right idea, but it's unclear from his terse post why his algorithm, described below in Python, is correct:
def candidates(hist):
    l = 0
    r = len(hist) - 1
    while l < r:
        yield (r - l - 1) * min(hist[l], hist[r])
        if hist[l] <= hist[r]:
            l += 1
        else:
            r -= 1

def maxwater(hist):
    return max(candidates(hist))

The proof of correctness is by induction: the optimal solution either (1) belongs to the candidates yielded so far or (2) chooses histograms inside [l, r]. The base case is simple, because all histograms are inside [0, len(hist) - 1].
Inductively, suppose that we're about to advance either l or r. These cases are symmetric, so let's assume that we're about to advance l. We know that hist[l] <= hist[r], so the value is (r - l - 1) * hist[l]. Given any other right endpoint r1 < r, the value is (r1 - l - 1) * min(hist[l], hist[r1]), which is less because r - l - 1 > r1 - l - 1 and hist[l] >= min(hist[l], hist[r1]). We can rule out all of these solutions as suboptimal, so it's safe to advance l.

