給你 n 個非負整數 a1,a2,...,an,每一個數表明座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別爲 (i, ai) 和 (i, 0) 。找出其中的兩條線,使得它們與 x 軸共同構成的容器能夠容納最多的水。面試
說明:你不能傾斜容器算法
「示例 1:」數組
輸入:[1,8,6,2,5,4,8,3,7] 輸出:49 解釋:圖中垂直線表明輸入數組 [1,8,6,2,5,4,8,3,7]。在此狀況下,容器可以容納水(表示爲藍色部分)的最大值爲 49。
「示例 2:」spa
輸入:height = [1,1] 輸出:1
「示例 3:」指針
輸入:height = [4,3,2,1,4] 輸出:16
「示例 4:」code
輸入:height = [1,2,1] 輸出:2
「提示:」圖片
這道題其實就是求最大面積,而面積的求法就是 底*高;
這道題的 底求法比較簡單,就是兩個下標的差值;高是 某段數組中最小的值。難就難在怎麼找到 最大的 底 * 高 的組合。這道題不斷的須要移動數組下標來尋找最大的面積,因此運用 「雙指針」 的思路來作就很合適,連個指針初始指向最左側最右側,至於怎麼移動,移動那個則須要經過所在的值來判斷,這裏作法是那邊的值小那個指針就向對方移動,緣由是:
先用 s 表示面積;heigth[left]表示左側指針的值;heigth[right] 表示右側指針的值。
s = Math.min(heigth[left], heigth[right]) * (right - left);
「若是移動的值大的指針,那麼所獲得的面積 s 必定不大於當前面積。」
你們想一想是否是這個理兒,由於 面積是由最小值決定的,若是移動最大值,那麼不管它移動後的值多大,都必定不大於當前的面積。因此每次移動都要移動值小的指針。接下來上代碼可能會更清晰一些。it
class Solution { public int maxArea(int[] height) { if (height == null || height.length < 1) { return 0; } int ans = 0; int left = 0, right = height.length - 1; // 當兩個指針沒有重合時 while (left < right) { // 求面試的方程式 int area = Math.min(height[left], height[right]) * (right - left); // 取最大的面積 ans = Math.max(ans, area); // 那個值小就移動那個指針 if (height[left] <= height[right]) { left ++; } else { right --; } } return ans; } }
這道題主要是要想到用 雙指針的方式來解決,由於雙指針能夠更動態的調整下標值;而後就是 指針的移動算法尤其重要,何時移動,怎麼移動的問題。io