leetCode 11 Container With Most Water
阿新 • • 發佈:2018-12-22
題目描述(中等難度)
每個陣列代表一個高度,選兩個任意的柱子往裡邊倒水,能最多倒多少水。
解法一 暴力解法
直接遍歷任意兩根柱子,求出能存水的大小,用一個變數儲存最大的。
public int maxArea(int[] height) {
int max = 0;
for (int i = 0; i < height.length; i++) {
for (int j = i + 1; j < height.length; j++) {
int h = Math.min(height[i], height[j]);
if (h * (j - i) > max) {
max = h * (j - i);
}
}
}
return max;
}
時間複雜度:O(n²)。
空間複雜度:O(1)。
解法二
我們理一下思路,大小是由長度和高度決定,如果選 0 到 8 就保證了長度最長,此時大小是 0 號柱子的高度 1 乘以長度 8 。我們如果想面積更大怎麼做呢,只能減小長度,增加高度。是左邊的柱子向右移動變成 1 號柱子呢?還是右邊的柱子向左移動變成 7 號柱子呢?當然是哪邊的柱子短就改哪邊的!只有這樣,高度才有可能增加。
例如我們如果把 8 號柱子變成 7 號柱子,此時長度減少了,然而高度還是 0 號柱子沒有變化,所以面積就會減少。把 1 號柱子變成 2 號柱子就很好了,因為此時高度就變成了 8 號柱子的高度,面積就有可能會增加。
如果左右兩邊柱子相等該怎麼辦呢?隨意!
我們假設 1 號 和 8 號 柱子高度是相等的。如果他們之間的柱子只有 1 根比它倆高或者沒有比它倆高的,那麼最大面積就一定選取是 1 號和 8 號了,所以 1 號接著變大,或者 8 號接著減小都是無所謂的,因為答案已經確定了。
假設 1 號 和 8 號之間有 2 根或以上的柱子比它倆高,假設是 4 號和 6 號比它倆高。1 號會變到 2 號、3 號,最終為 4 號,8 號會變到 7 號, 6 號,而在這個過程中產生的面積一定不會比 1 號和 8 號產生的面積大,因為過程中的柱子都比 1 號和 8 號低。所以是先變 1 號還是先變 8 號是無所謂的,無非是誰先到達更長的柱子而已。
看一下下邊的演算法,會更加清楚一些。
public int maxArea2(int[] height) {
int maxarea = 0, l = 0, r = height.length - 1;
while (l < r) {
maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));
if (height[l] < height[r])
l++;
else
r--;
}
return maxarea;
}
時間複雜度:O(n)。
空間複雜度:O(1)。
總
為了減少暴力解法的時間複雜度,只能去深層次的理解題意,從而找出突破點。