天天看點

11 Container With Most Water的數學證明 | LeetCode

11. Container with most water

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 and n is at least 2.

Example:

Input: [1,8,6,2,5,4,8,3,7]

Output: 49

網上給出的最優算法都比較類似,其基本想法是:将挑選的兩條邊分别從兩端$a_0, a_n$開始向中間移動,每一次隻能移動兩條邊中的一條。每次移動的标準是将較小的那條邊往中間移動一格。如果移動後的面積有所增長,則将面積最大值更新。當兩條邊相遇時,則停止。

網上幾乎都隻有這個算法的描述,而沒有提供一個嚴格的數學證明。和好友Meiyf讨論後,整理出這個算法的數學證明。

考慮分布在左右兩邊的移動名額$a_l, a_r$,它們分别從兩端$a_0, a_n$開始,通過$a_l$右移、$a_r$左移的方式,來搜尋最優解。

假設最優解為$a_i, a_j$,則我們有:$0 \leq i < j \leq n$。根據算法的移動方式,總是可以通過“$a_l$從$a_0$右移、$a_r$從$a_n$左移”若幹步的方式,到達$a_i, a_j$。

由于算法每一次隻能移動一步(即$a_l$右移一步或$a_r$左移一步),是以兩種情況:

  • $a_l$先到達$a_i$
  • $a_r$先到達$a_j$

必然有一種先發生。不妨假設$a_l$先到達$a_i$(那麼此時,$a_r$也就還未通過左移到達$a_j$,它還在$a_j$的右側)。那麼,我們隻需證明:

在現有的算法下,後續的更新步驟__都隻能是__:$a_r$不斷左移、直到到達$a_j$。

我們可以通過反證法來證明上述結論。

令函數$h(a_t)$表示點$a_t$對應的線段長度,令$w(a_s, a_t)$表示點$a_s$和$a_t$構成的線段長度。

若假設不成立,則存在某一步:在$a_r$還未通過左移到達$a_j$時,停留在$a_i$的$a_l$需要右移一步。

下面我們來證明不可能出現上面這種情況。

若上述發生,則我們有以下結論:

  1. $l = i < j < r$
  2. $h(a_i) = h(a_l) < h(a_r)$。因為根據算法,隻有長度更小的那一條邊才能向中間移動。是以,隻有當$h(a_l)$小于$h(a_r)$時,才可能出現$a_l$右移。

由此,我們可以得到由$a_i, a_r$兩條邊形成的面積為:

$$

S^* = h(a_i) * w(a_i, a_r).

這裡的高度之是以取為$h(a_i)$,是因為上面第2條已經說明了$h(a_i)$比$h(a_r)$小。

而此時,因為第1條已經說明$j < r$,是以$w(a_i, a_r) > w(a_i, a_j)$。是以我們有:

S^* = h(a_i) * w(a_i, a_r) > h(a_i) * w(a_i, a_j) \geq \min{\{h(a_i), h(a_j)\}} * w(a_i, a_j) = S_{max}

沖突。是以假設命題不成立,進而當$a_l$到達$a_i$後,後續的所有更新步驟都隻能是$a_r$不斷左移、直到到達$a_j$。

是以,在這樣的算法之下,一定能夠到找到面積的最優解$S_{max}$。

如果你喜歡我的文章或分享,請長按下面的二維碼關注我的微信公衆号,謝謝!

11 Container With Most Water的數學證明 | LeetCode

更多資訊交流和觀點分享,可加入知識星球:

11 Container With Most Water的數學證明 | LeetCode

繼續閱讀