Leetcode container with most water
Ok, so I made implementation very similar to yours with these modifications:


input is not being destroyed (althout it can still be adjusted to destroy it, but it just feels like such algorithm should not do this)
I compute maximum potential container area for values as I iterate them from left
I iterate the inner loop from end towards front
I use the potential to reduce the number of iterations of the inner loop.


function maxArea (input)
{
    // result value will go here
    let currentMax = 0;

    // we will need this value at least 2*(n-1) times:
    const limit = input.length - 1;

    // i&lt;limit because having i=limit would always yield zero size container so skip it:
    for(let i = 0; i &lt; limit; ++i) {
      const left = input[i];

      // zero size edge always yields zero size container so move to next i
      // this check may be omitted as the next will exclude it as well
      //if (left == 0) continue;

      // the largest container we can have on the right has this area:
      let potential = left * (limit - i);

      // if potential is not enough to get over currentMax, just move to next i
      if (potential &lt;= currentMax) continue;

      // search from end towards i becase more distant j is more likely to yield larger container and only the last j can actualy yield current potential
      for (let j = limit; j &gt; i; --j) {
        const right = input[j];

        // if right is at least as high as left then this container has the area equal to potential and no other j will do better for current left value
        if (right &gt;= left) {
          currentMax = potential;
          break;
        }

        // if it is smaller we check if its area is greater then currentMax and use it if it is
        const area = right * (j - i);
        if (area &gt; currentMax) currentMax = area;

        //decrease potential by 1 times left value because we will reduce distance by 1 for next iteration (--j):
        potential -= left;

        // if new potential is not enough to get over currentMax we can stop searching further j's and move to next i
        if (potential &lt;= currentMax) break;
      }
    }
    return currentMax;
}


In conjuction this algorithm is still (like yours) O(n^2) in time and O(1) in space. But it is a  better n^2 then yours, I believe. And (unlike yours) the actual performance will be different for different input values, not only for different lengths of the input array. It is same as yours in worst case (ie strictly decreasing sequence) and actualy O(n) in best case (ie increasing sequence). And of course anywhere in between for most of the possible variations of input values.

EDIT: hehe ok I benched it on random 100k value arrays and mine takes about 4ms, yours 15+ seconds :) The worst case scenario is about 15 seconds yours, 7 seconds mine. But the worst case scenario is very small set of all posibilities, so to get it from randomness is very unlikely. Randomness holds it on few ms. So improvement by factor of several thousands for random 100k value inputs :)