1. 程式人生 > >Leetcode演算法Java全解答--11. 盛最多水的容器

Leetcode演算法Java全解答--11. 盛最多水的容器

Leetcode演算法Java全解答–11. 盛最多水的容器

題目

盛最多水的容器

題目描述提示幫助提交記錄社群討論閱讀解答
給定 n 個非負整數 a1,a2,…,an,每個數代表座標中的一個點 (i, ai) 。

在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0)。
找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。

說明:你不能傾斜容器,且 n 的值至少為 2。
圖中垂直線代表輸入陣列 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示為藍色部分)的最大值為 49。

示例:

輸入: [1,8,6,2,5,4,8,3,7]
輸出: 49

想法

  1. 暴力破解
    2層迴圈,計算面積

    時間複雜度:O(n^2)

    空間複雜度:O(1)

  2. 雙指標法
    一個指標指向第一個資料

    一個指標指向最後一個數據

    算出面積,與已有面積對比

    將短的那條往長的那條靠攏

    返回結果

    時間複雜度:O(n)

    空間複雜度:O(1)

結果

超過23%的測試案例

超過69%的測試案例

總結

沒有想到使用雙指標法,感覺這樣子算起來資料不對

程式碼

我的答案

public class Solution011 {
    /**************************************
     * 題目
     11. 盛最多水的容器
     題目描述提示幫助提交記錄社群討論閱讀解答
     給定 n 個非負整數 a1,a2,...,an,每個數代表座標中的一個點 (i, ai) 。
     在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0)。
     找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。

     說明:你不能傾斜容器,且 n 的值至少為 2。
     圖中垂直線代表輸入陣列 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示為藍色部分)的最大值為 49。

     示例:
     輸入: [1,8,6,2,5,4,8,3,7]
     輸出: 49
     **************************************/

    /**************************************
     *
     * 想法:
     *          1. 暴力破解
     *              2層迴圈,計算面積
     *              時間複雜度:O(n^2)
     *              空間複雜度:O(1)
     *          2.雙指標法
     *              一個指標指向第一個資料
     *              一個指標指向最後一個數據
     *              算出面積,與已有面積對比
     *              將短的那條往長的那條靠攏
     *              返回結果
     *
     *              時間複雜度:O(n)
     *              空間複雜度:O(1)
     * 我的做法
     *      超過23%的測試案例
     *
     * 程式碼執行過程:
     *
     * 總結:
     *
     * ***********************************/

    public int maxArea(int[] height) {
        int maxVal = 0;
        int left = 0;
        int right = height.length - 1;

        while (left < right) {
            int dif = right - left;
            int leftVal = height[left];
            int rightVal = height[right];

            int value = calcArea(leftVal, rightVal, dif);
            maxVal = Math.max(maxVal, value);

            if (leftVal < rightVal) {
                left++;
            } else {
                right--;
            }
        }
        return maxVal;
    }

    /**
     * 暴力破解
     * 超過23%的測試案例
     *
     * @param height 陣列
     * @return
     */
    public int maxAreaByBrute(int[] height) {
        int maxVal = 0;
        for (int i = 0; i < height.length; i++) {
            for (int j = i + 1; j < height.length; j++) {
                int dif = j - i;
                int value = calcArea(height[i], height[j], dif);
                maxVal = Math.max(maxVal, value);
            }
        }
        return maxVal;
    }

    private static int calcArea(int i, int j, int dif) {
        int min = Math.min(i, j);
        return min * dif;
    }
}

大佬們的答案

/**************************************
 * 比我好的答案 better
 * ***********************************/
public int better(int[] height) {
    // 宣告變數
    int left = 0, right = height.length - 1, max = 0;
    while (left < right) {
        // 算出結果
        max = Math.max(Math.min(height[left], height[right]) * (right - left), max);
        if (height[left] < height[right]) {
            left++;
        } else {
            right--;
        }
    }
    return max;
}

測試用例

@Test
public void test011() {
    // 建立測試案例
    int[] arr1 = new int[] { 1, 8, 6, 2, 5, 4, 8, 3, 7 };

    // 測試案例期望值
    int expResult1 = 49;

    // 執行方法
    Solution011 solution011 = new Solution011();
    int result1 = solution011.maxArea(arr1);

    // 判斷期望值與實際值
    Assert.assertEquals(expResult1, result1);

}

其他

程式碼託管碼雲地址:https://gitee.com/lizhaoandroid/LeetCodeAll.git

檢視其他內容可以點選專欄或者我的部落格哈:https://blog.csdn.net/cmqwan

“大佬們的答案” 標籤來自leetcode,侵權請聯絡我進行刪改

如有疑問請聯絡,聯絡方式:QQ3060507060