对撞双指针(一) 盛水最多的容器

描述

给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水

1.你不能倾斜容器

2.当n小于2时,视为不能形成容器,请返回0

3.数据保证能容纳最多的水不会超过整形范围,即不会超过231-1

数据范围:

0<=height.length<=1050<=height.length<=105

0<=height[i]<=1040<=height[i]<=104

如输入的height为[1,7,3,2,4,5,8,2,7],那么如下图:

 【解法一】O(N^2)解法

class Solution {
public:
    int maxArea(vector<int>& height) {
        // write code here
        int n = height.size();
        if(n < 2)return 0;
        int res = 0;
        for(int i = 0; i < n-1; i++)
        {
            for(int j = i+1; j < n; j++)
            {
                int _minheight = min(height[i], height[j]);
                res = max(res, (j-i)*_minheight);
            }
        }
        return res;
    }
};

【解法二】双指针对撞

这道题利用了水桶的短板原理,较短的一边控制最大水量,因此直接用较短边长乘底部两边距离就可以得到当前情况下的容积。但是要怎么找最大值呢?

可以利用贪心思想:我们都知道容积与最短边长和底边长有关,与长的底边一定以首尾为边,但是首尾不一定够高,中间可能会出现更高但是底边更短的情况,因此我们可以使用对撞双指针向中间靠,这样底边长会缩短,因此还想要有更大容积只能是增加最短变长,此时我们每次指针移动就移动较短的一边,因为贪心思想下较长的一边比较短的一边更可能出现更大容积。

class Solution {
public:
    int maxArea(vector<int>& height) {
        // write code here
        if(height.size()<2)return 0;
        int res = 0;
        int left = 0, right = height.size()-1;
        while(left < right)
        {
            int capacity = min(height[left], height[right])*(right-left);   //当前容量
            res = max(res, capacity);   // 每次维护一个最大值
            if(height[left] < height[right]) // 短板移动
                left++;
            else
                right--;
        }
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值