Container With Most Water

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) 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

(2) j-left < right-left
 
因此S(left, right) > S(left, j<right)。排除了全部以left爲左邊界的組合,所以須要右移left。同理,當a(left) > a(right)時,須要左移right。而當a(left) = a(right)時,須要同時移動left和right。
 
可是以上策略在排除一側選擇時,並不能保證選擇另外一側能夠獲得比當前最大面積更大的面積,因此咱們須要保存maxArea,並不斷迭代,而不是用最終的l,r結果直接算出最大面積,這也是貪心和DP的區別之一。DP的狀態一般能夠直接獲得全局最優解。
 
因此上述解法須要經過證實來證實可使 maxArea保存全局最優,即l,r在某一時刻同時指向使maxArea最大的l *和r *
 
採用反證法來證實,即假設最終的結果並不是全局最優。即存在l,r在某一時刻同時指向使maxArea更大的l *和r *爲全局最優。再來考慮咱們的算法,由於最終l和r的停止狀況爲l==r,因此l和r遍歷了全部的下標index。左指針和右指針至少有一個曾通過全局最優的取值,即l到達l *或者r到達r *時,另外一個未曾到達過,否則maxArea最終會記錄了這個最大面積。不失通常性,假設l曾停在l *。由於l停在l *時,r未曾停在過r *上,因此當l停在l *後,後續只有l不停向右,通過了r*。
1)此時l停在l *上一段時間。r>r *,咱們移動r,可是始終沒法到達r*,移動r說明ar<al,可是a[j]>=a[r*](j>r*),因此min(a[l*],a[j])>=min(a[l*],a[r*]),顯然由a[l*],a[j]組成的面積更大,與l *和r *爲全局最優相違背。
2)r>r *,l到達l *後,繼續向右,說明,
 
附上leetcode上的證實,我以爲Since our algorithm stops only if the two pointers meet. So, we must have visited one of them but not the other這塊有問題,不是。

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!

相關文章
相關標籤/搜索