算法--------数组--------容纳最多的水

本文探讨了一种算法问题,即给定一系列垂直线,找出其中两条线与x轴构成的容器能容纳最多水的解决方案。通过双指针技巧,文章详细解释了如何高效地遍历并确定最大容量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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


在这里插入图片描述
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例:

输入: [1,8,6,2,5,4,8,3,7]
输出: 49

我的解答:

class Solution {
    public int maxArea(int[] height) {
           int length = height.length;
        if (length == 0) {
            return 0;
        }else if (length == 1){
            return height[0];
        }

        int max = 0;
        for (int i =0, j =length -1; j > i ;  ){
            int minHeight = Math.min(height[i], height[j]);
            max = Math.max(max,minHeight * (j -i));
            if (height[i] > height[j]) {
                j--;
            }else {
                i++;
            }
        }
        return max;
    }
}

看到网上优化过的之后:

class Solution {
    public int maxArea(int[] height) {
        int length = height.length;
        if (length == 0) {
            return 0;
        }else if (length == 1){
            return height[0];
        }

        int max = 0;
        for (int i =0, j =length -1; j > i ;  ){
            int start = height[i];
            int end = height[j];
            int minHeight = Math.min(start, end);
            max = Math.max(max,minHeight * (j -i));
            if (start > end) {
                do {
                    j--;
                }while (height[j]<end && j> i);
            }else {
                do {
                    i++;
                }while (height[i]<start && j> i);
            }
        }
        return max;
    }
}

下面分析下解题思路:

双索引,左右开弓。第一次遍历的肯定是左右两边的两个数。这时候,比较两个数,放弃比较小的那个数,继续遍历。为什么可以放过最小的那个数呢?
比如说左边的数,比右边的数小,那么对于左边那个数来说,他存在最大的值,就是最右边那个。因为对于左边那个数来说,和其他任何位置的组合,都没有最右边那个数大,所以,对于左边那个小的数,可以不用再遍历。一定是最大的组合。那么,这个数就可以不用遍历了。以此类推。时间复杂度是O(n);

依次类推可以得到每一个数和其他数组合的最大值。然后得出最大值就可以了。

总结:

1.看到别人的算法,总是可以让自己学到点什么。
2.解题思路很重要。思考问题的方式很重要。

解决过程:

刚开始,我做题的时候,同事在旁边,给我说了思路,左右遍历,然后小的数扔掉。当时,我担心的是,这样的话,会不会错失掉最大值?因为有些情况没有遍历,后来,我去尝试推翻同事的解法,后来发现,他是对的。思路就是上面我写的。嗯,我觉得,对任何人说的,都应该质疑,推翻,这会让你印象更深刻。这才有学习的意义。才有意思。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值