盛水最多的容器 贪心+双指针

描述

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


方法

容积=最短边*底边

左指针left从数组首向右扫描,右指针right从数组尾向左扫描, 

起始时刻,left指向首元素,right指向尾元素,容积=min(height[left],height[right])*(right-left)。

此时,左右两条边中有一条较短的边,不妨假设height[left]<=height[right],即左边的边较短。

下面有两种走法:

(1)左指针向右移动一步

容积=min(height[left+1],height[right])*(right-left-1)

height[right]不变,height[left+1]可能变大、也可能变小,(right-left-1)变小,容积有可能变大。

(2)右指针向左移动一步

容积=min(height[left],height[right-1])*(right-1-left)

height[left]不变,又因为height[left]<=height[right],所以最短边长min(height[left],height[right-1])不会变大,底边长(right-1-left)变小,容积变小。

因此,为寻找容积最大值,应当使较短边的指针移动(相当于进行了剪枝,已知某部分搜索空间不可能存在更优解,便不再搜索这一部分空间)。

搜寻终止条件:left>=right,变量res维护最大容积。


C++代码

class Solution {
public:
    int maxArea(vector<int>& height) {
        //排除不能形成容器的情况
        if(height.size() < 2) 
            return 0;
        int res = 0; 
        //双指针左右界
        int left = 0; 
        int 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;
    }
};

猜你喜欢

转载自blog.csdn.net/Seattle_night/article/details/127409188