LeetCode-第十一題:Container With Most Water

題目

題目.png

題意是說有n個非負的整數,他們分別以(i,ai)組成了n個點,每個點和(i,0)組成了垂直于x軸的直線,選取其中的兩條直線和X軸會組成一個凹槽,問凹槽能裝多少水。這題其實是求兩條直線和X軸能夠形成的最大面積,寬是兩個點之間X軸差的絕對值。高是兩個點中Y軸值最小的值。返回形成最大面積的值。

如下圖中的A點和H點(area=H*W=min(HA,HG)x(8-1)=1x7=7

分析

圖示.png

假設我們有上圖中圖示的點,該如何找滿足題意的兩條垂線呢?最簡單的就是窮舉所有的可能。任意選擇其中的兩條,求其中的最大值,但這樣會有很多多余的不必要計算。我們的思想是從兩邊往中間移動來計算最大的面積。

我們先假設有兩個索引點i和j,分別指向A點和H點。然后比較HA和HG,如果HA < HG則讓i往右移,指向B點,反之則讓j左移,指向G點。計算A和H形成的面積判斷是否更新原來的面積。剩余的點同理計算,直到i和j發生交叉。

這樣做能夠減少大量計算。如圖中的A和H兩個點。我們知道A點的高<H點的高,那么我們沒有必要再去計算A點去其他點形成的最大面積,因為A和H形成的寬度是最大的(這是為什么從兩端開始計算的原因,保證寬度最大),而A又是兩點之間最矮的,就是說A點與除了H點的其他點形成的面積是肯定小于和H點形成的面積(寬度小于H和A的寬度,高度最多小于等于A的高度)。這樣如果還有更大的面積形成,肯定是在除了A點以外剩余的點形成的,所以選擇移動i,將其指向B(保證寬度最大),在余下的點中找最大的面積。按照類似的思想計算下去,就能找到最大的面積。

代碼

代碼是java版,以C語言寫的話,應該會更快。

public class Solution 
{
    public int maxArea(int[] height) 
    {
        int arrSize=height.length;
        int max=0;
        int i=0;
        int j=arrSize-1;
        while(i<j)
        {
            int area=(j-i)*(height[i]<height[j]?height[i]:height[j]);
            max=area>max?area:max;
            if(height[i]<height[j])
            {
               i++;
            }
            else 
            {
                j--;
            }
        }   
        return max;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容