• LeetCode


    题目

    URL:https://leetcode.com/problems/container-with-most-water

    解法

    一、暴力破解

    暴力破解是妥妥超时。

    计算每一个水容器的体积,选出最大值。

        public int maxArea2(int[] height) {
            int maxArea = 0;
            for (int i = 0; i < height.length; i++) {
                for (int j = i + 1; j < height.length; j++) {
                    int maxHeight = height[i] < height[j] ? height[i] : height[j];
                    int curArea = maxHeight * (j - i);
                    if (curArea > maxArea) maxArea = curArea;
                }
            }
            return maxArea;
        }

    暴力破解,时间复杂度O(n2),运行时间约为 TLE

    二、双指针(Best Solution)

    左指针指向头,右指针指向尾 。首先计算出当前水容器体积,与之前最大水容器体积比较,若大于,更新最大水容器体积。之后指针移动:

    • 左指针对应的高度 >= 右指针对应的高度,此时右指针左移
    • 左指针对应的高度 < 右指针对应的高度,此时左指针右移

    原因是,最大水容器的体积,在左右指针向中间移动的过程中,取决于左右指针中最小的值。所以移左右指针之中较小的值有助于提升水容器的体积。

    证明:假设有个没有遍历到的最大水容器,其坐标为 maxLeft 和 maxRight。由于是对 height 数组遍历,那么我们肯定能遍历到 left 或者 right 之一。不妨假设现在遍历到 maxLeft 停下,此时还没有遍历到 maxRight,继续遍历有如下两种情况:

    • maxLeft 之后不向右遍历,直到 right 向左遍历结束。此时肯定遍历过 maxRight, 矛盾。
    • 到达maxLeft 之后还需要向右遍历。在该程序中,这种情况只可能在 right > left 产生,然而这说明了存在一个更大的水容器,与假设矛盾。

    两者都矛盾,故原最大水容器就是最大水容器。

    具体可以参考 Leetcode 官方题解证明

        public int maxArea(int[] height) {
            int start = 0, end = height.length - 1, maxArea = 0;
    
            while (start < end) {
                int bottom = end - start, minHeight;
                if (height[start] <= height[end]) {
                    minHeight = height[start];
                    start++;
                } else {
                    minHeight = height[end];
                    end--;
                }
                int curArea = bottom * minHeight;
                if (curArea > maxArea) maxArea = curArea;
            }
            
            return maxArea;
        }

    双指针,时间复杂度O(n),运行时间约为 8 ms

    总结

    解法很有技巧性,利用了贪心的思想。

  • 相关阅读:
    POJ1064 Cable master(二分 浮点误差)
    Codeforces1113F. Sasha and Interesting Fact from Graph Theory(组合数学 计数 广义Cayley定理)
    Codeforces1100F. Ivan and Burgers(离线+线性基)
    Codeforces1097D. Makoto and a Blackboard(数论+dp+概率期望)
    Codeforces1099F. Cookies(线段树+dp+贪心+博弈)
    python-zx笔记4-文件操作
    python-zx笔记3-函数
    python-zx笔记2-help
    fiddler使用笔记1
    理解OAuth 2.0
  • 原文地址:https://www.cnblogs.com/Piers/p/7192041.html
Copyright © 2020-2023  润新知