11 盛最多水的容器(暴力、双指针)

1. 问题描述:

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water

2. 思路分析:

① 首先我们最容易想到的是暴力破解,依次尝试所有可能的结果,需要使用两层循环,第一层循环表示左边的柱子,第二层循环表示的是第二层的柱子,水的容量取决于两根柱子较短的那个,最后较小的那根乘以柱子之间的距离即可解决,这个想法还是比较容易想到的,一开始的时候使用这个方法,没有想到暴力破解竟然通过了,之前领扣的测试用例中几乎暴力破解,普通型的递归都是通不过的,因为在最后的一两个数据它会设置得非常多所以会导致超时

② 在看了官方的题解之后,发现还是他们的思路太棒了,主要是通过分析得到使用双指针的方法来解决的,设置两个指针,开始的时候左指针指向的是最左边的柱子,右指针指向的是最右边的那根柱子,当发现哪一个的柱子比较短了那么就将哪一根的柱子往里面移动,因为较短的柱子是经过移动之后得到的结果可能比之前要大,所以需要进行计算之后才知道,在移动的过程中一定会经过容量最大的两根柱子,这个在领扣的题解中也有大佬证明一下:

3. 代码如下:

暴力破解代码如下:

class Solution {
    public int maxArea(int[] height) {
        /*首先是可以使用暴力破解来解决的*/
        int max = 0;
        for (int i = 0; i < height.length - 1; ++i){
            for (int j = i + 1; j < height.length; ++j){
                int cur = Math.min(height[i], height[j]);
                max = Math.max(max, cur * (j - i));
            }
        }
        return max;
    }
}

官方的双指针代码如下:

class Solution {
    public static int maxArea(int[] height) {
        int maxarea = 0, l = 0, r = height.length - 1;
        while (l < r) {
            maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));
            if (height[l] < height[r])
                l++;
            else
                r--;
        }
        return maxarea;
    }
}
发布了569 篇原创文章 · 获赞 153 · 访问量 59万+

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/105447750