美文网首页
【LeetCode】#011,盛最多水的容器

【LeetCode】#011,盛最多水的容器

作者: 小马要加油 | 来源:发表于2020-04-19 10:38 被阅读0次

    一、题目描述

    给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
    说明:你不能倾斜容器,且 n 的值至少为 2。
    来源:力扣(LeetCode)

    二、解题

    解题思路在源码中很详细标明

    三、源码

      /**
         * 简言之,这个算法是计算最大面积
         * 暴力法:把所有可能列举出来做比较
         * <p>
         * 执行用时 450 ms在所有 Java 提交中击败了16.95%的用户
         * 内存消耗 :39.9 MB, 在所有 Java 提交中击败了36.43%的用户
         */
    
        public int maxArea(int[] height) {
            int lenght = height.length;
            int result = 0;
            for (int i = 0; i < lenght; i++) {
                for (int j = i; j < lenght; j++) {
                    int min = Math.min(height[i], height[j]);
                    result = Math.max(result, min * (j - i));
                }
            }
            System.out.println(result);
            return result;
        }
    
        /**
         * 双指针法:
         * <p>
         * 执行用时 3 ms在所有 Java 提交中击败了92.82%的用户
         * 内存消耗 :40.3 MB, 在所有 Java 提交中击败了7.86%的用户
         *
         *         一次遍历就可以,所以比较一次就要把当前这根柱子最大的面积获取。
         *         假设第一根柱子(a1),当然是与比他高且最远(an)的那根面积最大。
         *         所以当a1<a你的时候,a1与之搭配的面积最大,再和其他面积做对比。
         *         如果a1>an,就让an往前移一点,也是第一种思路,只是换了个方向。
         * 这道题是参考网友的解法,实在是nb ,
         */
    
        public int maxArea2(int[] height) {
            int lenght = height.length;
            int result = 0, i = 0, j = lenght - 1;
            while (i < j) {
                if (height[i] < height[j]) {
                    System.out.println("height[j]:" + (height[j]) + " height[i]:" + height[i] + " width:" + (j - i) + " result:" + result);
                    result = Math.max(result, height[i] * (j - i));
                    i++;
                } else {
                    System.out.println("height[i]:" + (height[i]) + " height[j]:" + height[j] + " width:" + (j - i) + " result:" + result);
                    result = Math.max(result, height[j] * (j - i));
                    j--;
                }
            }
            System.out.println(result);
            return result;
        }    /**
         * 简言之,这个算法是计算最大面积
         * 暴力法:把所有可能列举出来做比较
         * <p>
         * 执行用时 450 ms在所有 Java 提交中击败了16.95%的用户
         * 内存消耗 :39.9 MB, 在所有 Java 提交中击败了36.43%的用户
         */
    
        public int maxArea(int[] height) {
            int lenght = height.length;
            int count = 0;
            int result = 0;
            for (int i = 0; i < lenght; i++) {
                for (int j = i; j < lenght; j++) {
                    int min = Math.min(height[i], height[j]);
                    result = Math.max(result, min * (j - i));
                    ++count;
                }
            }
            System.out.println("maxArea:执行了"+count+"遍,result = "+result);
            return result;
        }
    
        /**
         * 双指针法:
         * <p>
         * 执行用时 3 ms在所有 Java 提交中击败了92.82%的用户
         * 内存消耗 :40.3 MB, 在所有 Java 提交中击败了7.86%的用户
         *
         *         一次遍历就可以,所以比较一次就要把当前这根柱子最大的面积获取。
         *         假设第一根柱子(a1),当然是与比他高且最远(an)的那根面积最大。
         *         所以当a1<a你的时候,a1与之搭配的面积最大,再和其他面积做对比。
         *         如果a1>an,就让an往前移一点,也是第一种思路,只是换了个方向。
         * 这道题是参考网友的解法,实在是nb ,
         */
    
        public int maxArea2(int[] height) {
            int lenght = height.length;
            int result = 0, i = 0, j = lenght - 1,count = 0;
            while (i < j) {
                if (height[i] < height[j]) {
                    result = Math.max(result, height[i] * (j - i));
                    i++;
                } else {
                    result = Math.max(result, height[j] * (j - i));
                    j--;
                }
                ++count;
            }
            System.out.println("maxArea2:执行了"+count+"遍,result = "+result);
            return result;
        }
    

    四、附上github

    https://github.com/maryyMa/LeetCodeTest/commit/aa7fca7d7bf6c9c1f34fa190484335c6fdba874b

    五、总结:

    maxArea:执行了45遍,result = 49
    maxArea2:执行了8遍,result = 49
    

    这也难怪用双指针法只要3ms就能搞定了。算法的魅力就是在于做一道题有很多种解法,但我们一直在追求最优解。不过双指针占内存比较大,目前没有想法去优化,先记小本本,说不定哪天就突然顿悟了呢

    相关文章

      网友评论

          本文标题:【LeetCode】#011,盛最多水的容器

          本文链接:https://www.haomeiwen.com/subject/dkeybhtx.html