盛水最多的容器

1、題目描述

給你 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

「提示:」圖片

  • n = height.length
  • 2 <= n <= 3 * 104
  • 0 <= height[i] <= 3 * 104

2、思路分析:

  這道題其實就是求最大面積,而面積的求法就是 底*高;
  這道題的 底求法比較簡單,就是兩個下標的差值;高是 某段數組中最小的值。難就難在怎麼找到 最大的 底 * 高 的組合。這道題不斷的須要移動數組下標來尋找最大的面積,因此運用 「雙指針」 的思路來作就很合適,連個指針初始指向最左側最右側,至於怎麼移動,移動那個則須要經過所在的值來判斷,這裏作法是那邊的值小那個指針就向對方移動,緣由是:
   先用 s 表示面積;heigth[left]表示左側指針的值;heigth[right] 表示右側指針的值。
   s = Math.min(heigth[left], heigth[right]) * (right - left);
   「若是移動的值大的指針,那麼所獲得的面積 s 必定不大於當前面積。」
   你們想一想是否是這個理兒,由於 面積是由最小值決定的,若是移動最大值,那麼不管它移動後的值多大,都必定不大於當前的面積。因此每次移動都要移動值小的指針。接下來上代碼可能會更清晰一些。it

3、AC代碼

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;
    }
}

4、總結

   這道題主要是要想到用 雙指針的方式來解決,由於雙指針能夠更動態的調整下標值;而後就是 指針的移動算法尤其重要,何時移動,怎麼移動的問題。io

相關文章
相關標籤/搜索