一开始直接想用暴力法加剪枝擦边通过的,没想到还是超时了;
Leetcode:11.container-with-most-water(盛水最多的容器)_算法
谁知道最后输入从1-15000一共15000个数据,吓坏!
题解中得知双指针实现O(n),真的学到了,羡慕这些大佬的智商;
Leetcode:11.container-with-most-water(盛水最多的容器)_编程题_02
借鉴大佬题解:对O(n)的算法写一下自己的理解,一开始两个指针一个指向开头一个指向结尾,此时容器的底是最大的,接下来随着指针向内移动,会造成容器的底变小,在这种情况下想要让容器盛水变多,就只有在容器的高上下功夫。 那我们该如何决策哪个指针移动呢?我们能够发现不管是左指针向右移动一位,还是右指针向左移动一位,容器的底都是一样的,都比原来减少了 1。这种情况下我们想要让指针移动后的容器面积增大,就要使移动后的容器的高尽量大,所以我们选择指针所指的高较小的那个指针进行移动,这样我们就保留了容器较高的那条边,放弃了较小的那条边,以获得有更高的边的机会。

//暴力法
int maxArea(vector<int> &height)
{
    int len=height.size();
    if (len < 2)
        return 0; //元素不足2,非法

    int max = 0;
    int min = 0;
    int temp = 0;
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = i + 1; j < len; j++)  
        {
            if (height[i] != 0)//若除数为0 则非法
            {
                int nextJ = max / height[i];  //max对于当前height[i]最少要到height[j]才可能超过max
                if (max / height[i] >= len) //超出数组大小 则对于height[i] 永远超过不了max
                    continue; //直接下一步
                if (nextJ > j)   //nextJ>j 说明至少要到height[nextJ]位置才可能超过max
                    j = nextJ; 
            }

            min = height[i] < height[j] ? height[i] : height[j];
            temp = min * (j - i);
            if (temp > max)
                max = temp;
        }
    }
    return max;
}
//双指针法
 int maxArea(vector<int>& height) {
   int size = height.size();
    int left=0, right=size-1;
    int ans = 0;
    while(left < right){
        ans = max(ans, (right-left)*min(height[left], height[right]));
        if(height[left] > height[right]) --right;
        else ++left;
    }
    return ans;
}