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.html
Note: You may not slant the container.算法
這道題給出了一個序列,要求找出兩根線使其和x軸之間的存儲的水最多。注意這裏最終盛多少水,不須要考慮中間的最低值,只須要考慮兩邊的邊界。ide
leetcode給出的提示是用two pointer來作,two pointer作了幾題,基本是O(n)複雜度,使用貪心策略。this
具體採用何種貪心策略,我也作了好幾回選擇,最終的選擇以下:指針
1.給出l = 0, r = n-1.code
2.當al < ar, l++,向右移動一步,不然 r--,向左移動一步。orm
首先說明爲什麼採用此種策略。思考以下,轉自Yangbing Shi的博客:htm
因爲ai和aj (i<j) 組成的container的面積:S(i,j) = min(ai, aj) * (j-i)blog
因此對於任何S(i'>=i, j'<=j) >= S(i,j),因爲j'-i' <= j-i,必然要有min(ai',aj')>=min(ai,aj)才行。一樣能夠採用頭尾雙指針向中間移動:
當a(left) < a(right)時,對任何j<right來講
(1) min(a(left),aj) <= a(left) = min(a(left), a(right))leetcode
Here is the proof. Proved by contradiction:
Suppose the returned result is not the optimal solution. Then there must exist an optimal solution, say a container with aol and aor (left and right respectively), such that it has a greater volume than the one we got. Since our algorithm stops only if the two pointers meet. So, we must have visited one of them but not the other. WLOG, let's say we visited aol but not aor. When a pointer stops at a_ol, it won't move until
The other pointer also points to aol. In this case, iteration ends. But the other pointer must have visited aor on its way from right end to aol. Contradiction to our assumption that we didn't visit aor.
The other pointer arrives at a value, say arr, that is greater than aol before it reaches aor. In this case, we does move aol. But notice that the volume of aol and arr is already greater than aol and aor (as it is wider and heigher), which means that aol and aor is not the optimal solution -- Contradiction!