【leetcode】双指针_11盛水最多的容器

目录

题目链接:

题目描述:

分析

暴力解法

对撞双指针

参考文章


题目链接:

TT11. 盛最多水的容器 - 力扣(LeetCode)​​​​​​​

题目描述:

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

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

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

说明:你不能倾斜容器。


​​​​​​​

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

 分析

容积 = 长X宽 = 底 X高 = 间距 X最小的高度

如果使得盛水最多,

  1. 高要足够大,但是根据木桶原理的话,我们选择的高,应该是容器两边中更小的一边,才能保证水不会溢出。即使 6 号的高度是最高,我们选择 1 和 6 的话,计算出来的体积是 5 x 8 = 40 ,是小于 49 的,所以也不能选
  2.    还要考虑宽

暴力解法(会超时)

把所有情况全部遍历一遍。

利用两层循环,外层固定一个数组,内层一次往后找数组,当有更大的出现,就记录这个更大体积和两数组的位置。

//找比较小的
int getMin(int a, int b) 
{
    if (a < b)
        return a;
    else
        return b;
}
 
//暴力解法
int maxArea1(int* height, int heightSize) {

    int maxArea = 0;

    for (int i = 0; i < heightSize; i++)
    {
        //面积 = min(a,b) * (b-a)
        for (int j = i + 1; j < heightSize; j++)
        {
            int min = getMin(height[i], height[j]);
            int tmp = min * (j - i);

            if (tmp > maxArea)
                maxArea = tmp;
        }
    }
    return maxArea;
}

对撞双指针

初始化 left 和 right ,在数组头部、尾部

int left = 0, right = heightSize -1;
int  maxArea = 0;

那怎么确定怎么移动letf和right呢?

left, right 在两端,移动间距只能变小。

因为移动间距减小了,那么代表容积=间距 X最小的高度,想要容积再大,只能移动高度,来减少面积的减少程度。选择高度更大的木板,可以尽量避免容积的减少。

int getMin(int a, int b) 
{
    if (a < b)
        return a;
    else
        return b;
}
 
int maxArea(int* height, int heightSize) {
    //定义双指针,指向数组头尾
    int left = 0, right = heightSize -1;
    int  maxArea = 0;

    while (left < right)
    {
        //h 高  wide宽
        int h = getMin(height[left], height[right]);
        int wide = right - left;

        //临时面积
        int area = h * wide;

        //更新maxArea
        if (area > maxArea)
            maxArea = area;
        
        //选取更高的木板
        //一旦有一个木板更短,就移动这个木板
        if (height[left] < height[right])
            left++;
        else
            right--;
    }

    return maxArea;
}

参考文章

http://t.csdnimg.cn/spwg1icon-default.png?t=N7T8http://t.csdnimg.cn/spwg1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

景鹤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值