Container With Most Water (頭尾指針的妙用)

 

   對於數組 A , 怎麼求的Max((j - i) * [min (A[i] , A[j])]) , 其中 i , j < A.length - 1

 

   這道題目, 暴力的話,很容易, O(n^2) , 可是採用頭尾指針的方法可以在O(n)的時間內完成!

 

   O(n) 的代碼 及其簡單,就是頭尾指針,誰小誰移動,然後,求兩個指針間的面積,再更新

   最大面積即可。

 

   但是,爲什麼?爲什麼這個方法能行了?

   比如 : 數組A[3 , 7 , 4 , 8 , 5]

   暴力的話,就是:

   3 7 3

   3 4 6

   3 8 9

   3 5 12

   7 4 4

   .....

   8 5 5

 

   觀察上面的可以知道:

   以A[0] = 3 爲一條邊的話,那麼高度最大爲3 , 所以,如果底邊能最大 , 就能找到最大面積

   所以,就可以採用尾指針從尾部遍歷。

 

   如果它比3小,那麼就要在0 - A.length - 2中找 , 因爲在這裏面可能還存在面積更大的,而這個

   面積最大的臨界情況就是第一個>=3! 因爲滿足底最大! 那麼接下來就不要比較A[1],A[2],A[3] 構成的大小,他們 一定比A[0]A[4]小!這樣不就減少了沒用的計算。直接進入A[1] = 7;

 

  同理,以A[1] = 7 爲高 , 查找第一個>=7的 , 但是,可能會想,已經過濾的尾部的元素

  不會與7構成一個更大的元素嗎?比如,如果上面數組在5後面有一個2 , 那麼以A[0] = 3爲邊時,就已經

  被過濾掉了,不會在於其他元素比較了?爲什麼這能行了?

  可以這樣考慮,它既然比3小,那麼他就一定比7小(因爲只有最小的那個元素在移動的啊),對吧!所以,

  它與3爲邊時,底邊還長1了,怎麼可能與7再構成一個更大的面積!這又是在去除沒用的計算。

  所以,7 就只要關心,看能否與當前尾指針所指的元素及其前面的元素構成一個更大面積!

  如此,一路遍歷,直到頭指針 >= 尾指針 

 

 

  總結:

  關鍵的地方就在於頭尾指針的使用,我覺得他們的作用就是一種標誌!

  標誌,實際可能產生最大面積的範圍

  以上只是個人的一些粗陋的理解.......

   

   代碼:

 

public static int maxArea(int[] height) {
        int maxWater=0, left=0, right=height.length-1;
//頭尾指針
        while(left<right) {
            maxWater = Math.max(maxWater,(right-left)*Math.min(height[left], height[right]));
            if(height[left]<height[right]) left++;
            else right--;
        }
        return maxWater;
    }

 

發佈了121 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章