hot100-盛最多水的容器

7.盛最多水的容器

题目描述

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i])

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

思路:

最开始的做法,用双指针,左指针:若当前start大于左指针位置数值,必然不可能选它(当前start远且大),若小于则比较,以当前end为右挡板,判断start为左挡板和左指针为左挡板谁面积更大。右指针与其类似。但是这种做法只能适合部分场景,比如start当前停在了一个比右指针小很多的挡板,右指针即使值很大,也可能被跳过,但是实际上左指针还没有到的地方有比右指针值还大的挡板,例如

{1,1,1,1,1,100,99,1}

然后开始尝试暴力破解,以每根挡板为较短的那根,然后寻找所有比他大的挡板求面积进行比较,但是这种直接暴力破解会超时

后又对上面的暴力破解做优化,对每一根挡板,分别从0和length-1开始寻找比他大的挡板,找到后即可退出循环,因为我们最后选定的一定是距离他更远的那根挡板。

题解提供的思路:

双指针,一左一右,指针要移动必然造成宽度减小,那么现有较短的边如果保留必然使得面积变小,所以可以舍弃,但是较常边保留有可能使得面积变大,所以每次移动的指针是较短边的那边。

代码:

public static int maxArea2(int[] height){
        if(height.length<=1)return 0;
        //记录以每个挡板为较低板得最大area
        int area = 0;
        for (int i = 0; i < height.length; i++) {
            //int tmp = 0;
//            for(int j = 0;j < height.length;j++){
//                if(i==j||height[i] > height[j])continue;
//                tmp = Math.max(height[i]*(Math.abs(j-i)),tmp);
//            }
            //找到距离它最远的大于等于他的木板
            int l = 0;
            int r = height.length;
            boolean flag1 = false;
            boolean flag2 = false;
            for (int j = 0; j < i; j++) {
                if(height[j]>=height[i]){
                    l = j;
                    flag1 = true;
                    break;
                }
            }
            for (int k = height.length-1; k > i ; k--) {
                if(height[k] >= height[i]){
                    r = k;
                    flag2 = true;
                    break;
                }
            }
            if(flag1&&flag2){
                area = Math.max(Math.max(i-l,r-i)* height[i],area);

            }else if(flag1&&(!flag2)){
                area = Math.max((i-l)* height[i],area);
            }else if(!flag1&&flag2){
                area = Math.max((r-i)* height[i],area);
            }

            //area = Math.max(tmp,area);
        }
        return area;

    }

参考题解后代码

public static int maxArea3(int[] height){
    int l = 0;
    int r = height.length-1;
    int res = 0;
    while(l<r){
        res = Math.max(Math.min(height[l],height[r])*(r - l),res);
        if(height[l]<=height[r])l++;
        else r--;
    }
    return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值