LeetCode 题解 #11 Container With Most Water

LeetCode 题解 #11 Container With Most Water

1. 题意

​    给定n个非负整数,a1,a2 , … , an;每一个表示一个坐标点(i,ai),然后每个点画一条垂线到x轴,要找到两条线,和x轴构成一个装水的容器,使容积(面积)最大。注意:不能倾斜容器(例图情况倾斜可装更多)。

2. 思路

​    记录 ”向左、右最远大于等于a[i]的下标值” 不可行,会产生回溯,但如果考虑线段长度是小等于10e4的非负整数这个性质,起码可以知道,某个高度的线段,其出现的最小下标imin[]、最大下标imax[];可以理解成高度为x的线段的最左,最右位置;然后进一步,可以知道,高度大等于x的线段的最左位置Lmp[x],高度大等于x的线段的最右位置Rmp[x],然后枚举x,很明显,在水高x的条件下,x * (Rmp[x] - Lmp[x]) 就是最大容积,取其最大值即可。

3. 细节

​    怎么求 “高度大等于x的线段的最左、右位置” ?从大到小遍历线段长x,维护一个下标当前最小、最大值,如果在某个x上,下标当前最小值小于imin[x],就更新之,相当于用更高的线段向左拓展,反之亦然。

4. 代码

   class Solution {
     
   public:
       #define mmin(a,b) (a
       #define mmax(a,b) (a>=b?a:b)
       int imin[10007];
       int imax[10007];
       int tmax = -1;
       int tmin = 99999;
       int maxArea(vector<int>& height) {
     
           for(int i=0;i<10007;i++)//初始值
           {
     
               imin[i] = 99999;
               imax[i] = -1;
           }
           for(int i=0;i<height.size();i++)
           {
     
               imin[height[i]] = mmin( (imin[height[i]]) , (i) );//某一高度值对应最左下标
               imax[height[i]] = mmax( (imax[height[i]]) , (i) );
               tmax = mmax(tmax,height[i]);
               tmin = mmin(tmin,height[i]);
           }
           int curmin = 99999;
           int curmax = -1;
           for(int t = tmax;t >= tmin;t--)// t为线段高
           {
     
               curmin = mmin(curmin,imin[t]);
               curmax = mmax(curmax,imax[t]);
               if(imin[t] > curmin)
                   imin[t] = curmin;
               if(imax[t] < curmax)
                   imax[t] = curmax;
           }//此时的imin[x]为高度大等于x线段的最左下标
           int areamax = -1;
           for(int t = tmin;t <= tmax;t++)
           {
     
               areamax = mmax( ((imax[t]-imin[t]) * t) , areamax);
           }
           return areamax;
       }
   };

你可能感兴趣的:(LeetCode,算法,c++,leetcode)