Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.
這道求裝最多水的容器的題和那道 Trapping Rain Water 收集雨水 很類似,但又有些不同,那道題讓求整個能收集雨水的量,這道只是讓求最大的一個的裝水量,而且還有一點不同的是,那道題容器邊緣不能算在裡面,而這道題卻可以算,相比較來說還是這道題容易一些,我們需要定義i和j兩個指標分別指向陣列的左右兩端,然後兩個指標向中間搜尋,每移動一次算一個值和結果比較取較大的,容器裝水量的演算法是找出左右兩個邊緣中較小的那個乘以兩邊緣的距離,程式碼如下:
C++ 解法一:
class Solution { public: int maxArea(vector<int>& height) { int res = 0, i = 0, j = height.size() - 1; while (i < j) { res = max(res, min(height[i], height[j]) * (j - i)); height[i] < height[j] ? ++i : --j; } return res; } };
Java 解法一:
public class Solution { public int maxArea(int[] height) { int res = 0, i = 0, j = height.length - 1; while (i < j) { res = Math.max(res, Math.min(height[i], height[j]) * (j - i)); if (height[i] < height[j]) ++i; else --j; } return res; } }
這裡需要注意的是,由於Java中的三元運算子A?B:C必須須要有返回值,所以只能用if..else..來替換,不知道Java對於三元運算子這麼嚴格的限制的原因是什麼。
下面這種方法是對上面的方法進行了小幅度的優化,對於相同的高度們直接移動i和j就行了,不再進行計算容量了,參見程式碼如下:
C++ 解法二:
class Solution { public: int maxArea(vector<int>& height) { int res = 0, i = 0, j = height.size() - 1; while (i < j) { int h = min(height[i], height[j]); res = max(res, h * (j - i)); while (i < j && h == height[i]) ++i; while (i < j && h == height[j]) --j; } return res; } };
Java 解法二:
public class Solution { public int maxArea(int[] height) { int res = 0, i = 0, j = height.length - 1; while (i < j) { int h = Math.min(height[i], height[j]); res = Math.max(res, h * (j - i)); while (i < j && h == height[i]) ++i; while (i < j && h == height[j]) --j; } return res; } }
參考資料:
https://discuss.leetcode.com/topic/16754/simple-and-fast-c-c-with-explanation