LeetCode Container With Most Water

題目:Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

就是說,x軸上在1,2,…,n點上有許多垂直的線段,長度依次是a1, a2, …, an。找出兩條線段,使他們和x抽圍成的面積最大。面積公式是 Min(ai, aj) X |j - i|

解法1:大家都能想到的,窮舉所有(i,j)可能,找一個最大的。

這裏有一點比較重要,第一層遍歷是以i 爲右邊界,這樣我們每輪遍歷的最大length就定了,就可以有優化的空間,否則如果以i爲左邊界,那麼往右遍歷,length也添加,value又是不定值,就多了個變量

//O(n^2)
     public static int maxArea(int[] height) {
         // Start typing your Java solution below
         // DO NOT write main() function
         int maxArea = 0;
         for(int i = 1; i < height.length; i++){
             if(height[i] == 0)continue;
             for(int j = 0; j < i; j++) {
                 int area = area(height,i,j);
                 if(area > maxArea) {
                     maxArea = area;
                 }
             }
         }
         return maxArea;
     }

O(n^2)窮舉
//不過這樣的話無法通過leetcode大集合。

解法2:可以對解法1中的第二個循環中的j做預先判斷從而跳過某些情況,做一點優化。在我們檢查比i小的各個j時,計算面積的短板不會超過ai本身。平均到距離上,如果距離小於這個平均距離那就可以跳過了。

public static int maxArea(int[] height) {
         // Start typing your Java solution below
         // DO NOT write main() function
         int maxArea = 0;
         for(int i = 1; i < height.length; i++){
             if(height[i] == 0)continue;
             int maxPossibleIdx = i - maxArea/height[i];
             for(int j = 0; j < i && j <= maxPossibleIdx; j++) {
                 int area = area(height,i,j);
                 if(area > maxArea) {
                     maxArea = area;
                 }
             }
         }
         return maxArea;
     }

O(n^2)預判斷

解法3: O(n)的複雜度。保持兩個指針i,j;分別指向長度數組的首尾。如果ai 小於aj,則移動i向後(i++)。反之,移動j向前(j–)。如果當前的area大於了所記錄的area,替換之。
這個想法的基礎是,如果i的長度小於j,無論如何移動j,短板在i,不可能找到比當前記錄的area更大的值了,只能通過移動i來找到新的可能的更大面積。

這裏也是因爲我們是從頭尾開始遍歷,使得length本身是最大的。少了一個變量,這很重要!!!

public static int maxArea(int[] height){
        int maxArea = 0;
        int i = 0;
        int j = height.length - 1;
        if(j <=0)return 0;
        while(i < j) {
            int area = area(height, i, j);
            if(height[i] < height[j]){
                i++;

            }else {
                j--;
            }
            if(area > maxArea) maxArea = area;
        }
        return maxArea;
    }

O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章