1. 程式人生 > >[leecode]---11.container with most water

[leecode]---11.container with most water

description:

 

Input: [1,8,6,2,5,4,8,3,7]Output: 49


思路
1

  從(1,a1)開始向後算面積,需要兩層n迴圈,時間複雜度n2

思路2

  找出陣列中最大的數,將其與次大,第三大數求面積,依次類推,也需要兩層迴圈,還需要額外排序,時間複雜度n2

  因為找出最大數並且並不知道輸入資料的規律(有可能很雜亂),所以每個都有必要算,採取思路1.

  程式碼實現如下:

class Solution {
    public int maxArea(int
[] height) { int max = 0; for(int i = 0; i < height.length; i++){ int mid = maxSpare(height, i); max = max >= mid ? max : mid; } return max; } // 從index = start開始向後對每一對求面積 private int maxSpare(int[] height, int start){ int
maxArea = 0; for(int i = start + 1; i < height.length; i++){ int area = countArea(height[start], height[i], i - start); maxArea = maxArea > area ? maxArea : area; } return maxArea; } private int countArea(int height1, int height2, int width){
int result = 0; int height = height1 > height2 ? height2 : height1; result = height * width; return result; } }

but only faster 15.40% of Java online submissions for Container With Most Water.

 

討論區看見O(n)的演算法:

(1)left = 0, right = n-1,計算left~right之間的面積

(2)若left的高度小於right的高度,則查詢2~n-1之間大於left的位置,更新left,計算面積;否則,查詢中間大於right高度的位置,作為新right,計算面積

(3)直到right< left

 

思考:

  設以left=1為基點不變,找到一個right值,使left~right之間的矩形面積最大,則存在以下三種情況:

aleft > aright

 

  此時高度height=arightwidth=n-1),所求面積可能小於等於a1為左邊的最大面積。

aright為右邊起第一個大於等於aleft的邊,設right=n-1

 

  此時height=aleftwidth= (n-1)-1,面積有可能等於為以a1為左邊的最大面積。

aright為右邊起第一個大於等於aleft的邊,設right=n-2

 

  此時雖然height=aleft,但是width=(n-2)-1小於②中的width,所以③中求得的面積小於②中的面積,即③中的情況是不考慮的

  所以可以兩頭推進。參考如下程式碼:

class Solution {
    public int maxArea(int[] height) {
        int max = 0, left = 0, right = height.length-1;
        while(left < right){
            int area = Math.min(height[left],height[right]) * (right - left);
            max = max > area ? max : area;
            if(height[left] < height[right]){
                int base = height[left];
                while((height[left] <= base) && (left < right)){
                    left++;
                } // end while
            }
            else{
                int base = height[right];
                while((height[right] <= base) && (left < right)){
                    right--;
                } // end right
            } // end if-else
        } // end while
        return max;
    } // end maxArea
}
Runtime: 7 ms, faster than 55.28% of Java online submissions for Container With Most Water.

 

演算法很重要 

 

一個3ms的程式碼:

class Solution {
  public int maxArea(int[] height) {
    int maxarea = 0;
    int temparea = 0;
    int i = 0;
    int j = height.length -1;
    while(i < j) {
      if(height[i] <= height[j]) {
        temparea = height[i] * (j-i);
        i++;
      }
      else {
         temparea = height[j] * (j-i);
         j--;
      }
      if(temparea > maxarea) {
         maxarea = temparea;
      }
    }
    return maxarea;
  }
}