微信公衆號:程序員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),結合木桶效應,長方形的長取決於相對短的。得出以下公式:
求最大容量則需要計算出所有可能的容量,取其中最大值。
方法1 採用雙指針法
-
確定左右指針
左指針 left :數組的第0個元素
右指針 right :數組的最後一個元素
-
計算容量(長方形面積)
-
挪動指針
條件:將指針指向元素較小的指針向另一個指針靠近一個單位
-
計算指針移動後容量,並與之前的最大容量做比較,更新最大容量值。
-
重複步驟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()
空間複雜度O(1)