【LeetCode每日一題】盛最多水的容器

微信公衆號:程序員Alex
關注可瞭解更多的編程知識。問題或建議,請公衆號留言;
如果你覺得文章對你有幫助,歡迎關注分享

盛最多水的容器

給你 n 個非負整數 a1,a2,…,an,每個數代表座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別爲 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/container-with-most-water
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

說明

你不能傾斜容器,且 n 的值至少爲 2。

圖中垂直線代表輸入數組 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示爲藍色部分)的最大值爲 49。

示例:

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

解題思路

​ 通過分析題目,結合圖表可以發現,此題其實就是求數組元素組成的長方形的最大面積。數組中的元素代表長方形的長,兩個元素之間的距離(座標差)就是長方形的寬。取數組中的第m和第n個數(滿足m < n),結合木桶效應,長方形的長取決於相對短的。得出以下公式:

=Min(height[m],height[n])長 = Min(height[m] , height[n])
=nm寬 = n - m
=Min(height[m],height[n])(nm)容量 = Min(height[m] , height[n])* (n-m)
求最大容量則需要計算出所有可能的容量,取其中最大值。

方法1 採用雙指針法

  1. 確定左右指針

    左指針 left :數組的第0個元素

    右指針 right :數組的最後一個元素

  2. 計算容量(長方形面積)

    maxArea=Min(height[left],height[right])(rightleft)maxArea = Min(height[left] , height[right])* (right-left)

  3. 挪動指針

    條件:將指針指向元素較小的指針向另一個指針靠近一個單位

  4. 計算指針移動後容量,並與之前的最大容量做比較,更新最大容量值。

  5. 重複步驟3和4,直至指針相遇。

核心代碼實現

完整代碼:https://github.com/tinet-shenjg/leetCode4J

/**
 * 計算最大容量
 *
 * @param height n 個非負整數集合
 *
 * @return 最大容量
 */
public static int maxArea(int[] height) {
    // 定義最大容量
    int maxArea = 0;

    // 採用雙指針來計算最大容量
    int left = 0;
    int right = height.length - 1;

    // 指針第一次相遇爲終結點
    while (left < right) {
        // 計算當前的最大容量
        maxArea = Math.max(maxArea, Math.min(height[left], height[right]) * (right - left));

        // 移動指針,相對短的木板向另一側一定
        if (height[left] > height[right]) {
            right--;
        } else {
            left++;
        }
    }
    return maxArea;
}

測試用例

public static void main(String[] args) {
        int[] height = {1, 8, 6, 2, 5, 4, 8, 3, 7};
        System.out.println(maxArea(height));
        System.out.println(maxArea2(height));
 }

複雜度分析

時間複雜度O(n)

空間複雜度O(1)

方法2 暴力窮舉

​ 不推薦此方法,兩層循環遍歷數組即可。

代碼實現

 public static int maxArea2(int[] height) {
        int maxarea = 0;
        for (int m = 0; m < height.length; m++){
        		for (int n = m + 1; n < height.length; n++){
            		maxarea = Math.max(maxarea, Math.min(height[m], height[n]) * (n - m));
            }
        }      
        return maxarea;
    }

複雜度分析

時間複雜度O(n2n^2)

空間複雜度O(1)
在這裏插入圖片描述

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