★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-ofmkybhi-me.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
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.git
Note: You may not slant the container and n is at least 2.github
The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.算法
Example:數組
Input: [1,8,6,2,5,4,8,3,7] Output: 49
給定 n 個非負整數 a1,a2,...,an,每一個數表明座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別爲 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器能夠容納最多的水。微信
說明:你不能傾斜容器,且 n 的值至少爲 2。this
圖中垂直線表明輸入數組 [1,8,6,2,5,4,8,3,7]。在此狀況下,容器可以容納水(表示爲藍色部分)的最大值爲 49。spa
雙指針法3d
這種方法背後的思路在於,兩線段之間造成的區域老是會受到其中較短那條長度的限制。此外,兩線段距離越遠,獲得的面積就越大。指針
咱們在由線段長度構成的數組中使用兩個指針,一個放在開始,一個置於末尾。 此外,咱們會使用變量 maxareamaxarea 來持續存儲到目前爲止所得到的最大面積。 在每一步中,咱們會找出指針所指向的兩條線段造成的區域,更新 maxareamaxarea,並將指向較短線段的指針向較長線段那端移動一步。
查看下面的例子將有助於你更好地理解該算法:1 8 6 2 5 4 8 3 7
這種方法如何工做?
最初咱們考慮由最外圍兩條線段構成的區域。如今,爲了使面積最大化,咱們須要考慮更長的兩條線段之間的區域。若是咱們試圖將指向較長線段的指針向內側移動,矩形區域的面積將受限於較短的線段而不會得到任何增長。可是,在一樣的條件下,移動指向較短線段的指針儘管形成了矩形寬度的減少,但卻可能會有助於面積的增大。由於移動較短線段的指針會獲得一條相對較長的線段,這能夠克服由寬度減少而引發的面積減少。
120ms
1 class Solution { 2 func maxArea(_ height: [Int]) -> Int { 3 var maxarea:Int = 0, l:Int = 0, r:Int = height.count - 1 4 while(l < r) 5 { 6 maxarea = max(maxarea, min(height[l], height[r]) * (r - l)) 7 if height[l] < height[r] 8 { 9 l += 1 10 } 11 else 12 { 13 r -= 1 14 } 15 } 16 return maxarea 17 } 18 }
20ms
1 class Solution { 2 func maxArea(_ height: [Int]) -> Int { 3 var left = 0 4 var right = height.count - 1 5 var maxArea = area(height, left, right) 6 while(left < right) { 7 if (height[left] < height[right]) { 8 left = left + 1 9 } else { 10 right = right - 1 11 } 12 let lArea = area(height, left, right) 13 if (lArea > maxArea) { 14 maxArea = lArea 15 } 16 } 17 return maxArea 18 } 19 20 func area(_ height: [Int], _ start: Int, _ end: Int) -> Int { 21 let x = height[start] 22 let y = height[end] 23 return (end - start) * (x > y ? y : x) 24 } 25 26 }
20ms
1 class Solution { 2 func maxArea(_ height: [Int]) -> Int { 3 var result = 0 4 5 var left = 0; 6 var right = height.count - 1; 7 8 while left < right { 9 var valleft = height[left] 10 var valright = height[right] 11 let area = (valleft > valright ? valright : valleft) * (right - left) 12 13 if area > result { 14 result = area 15 } 16 17 if valleft > valright { 18 right -= 1 19 } else { 20 left += 1 21 } 22 } 23 return result 24 } 25 }
24ms
1 class Solution { 2 func maxArea(_ height: [Int]) -> Int { 3 var ans = 0 4 5 var i = 0 6 var j = height.count - 1 7 8 while i < j { 9 let h1 = height[i] 10 let h2 = height[j] 11 12 let area = abs(i - j) * min(h1, h2) 13 ans = max(ans, area) 14 15 if h1 < h2 { i += 1 } 16 else { j -= 1 } 17 } 18 19 return ans 20 } 21 }
28ms
1 class Solution { 2 func maxArea(_ height: [Int]) -> Int { 3 var area = 0 4 var left = 0 5 var right = 0 6 7 var i = 0 8 var j = height.count - 1 9 10 while i < j { 11 if left <= right { 12 let tmpArea = left * (j - i) 13 area = area < tmpArea ? tmpArea : area 14 if left < height[i] { 15 left = height[i] 16 } else { 17 i += 1 18 } 19 } else { 20 let tmpArea = right * (j - i) 21 area = area < tmpArea ? tmpArea : area 22 if right < height[j] { 23 right = height[j] 24 } else { 25 j -= 1 26 } 27 } 28 } 29 return area 30 } 31 }
40ms
1 class Solution { 2 func maxArea(_ height: [Int]) -> Int { 3 var result = 0 4 var i = 0 5 var j = height.count - 1 6 7 while (i < j) { 8 let minHeight = min(height[i], height[j]) 9 let area = minHeight * (j - i) 10 result = max(result, area) 11 while (height[i] <= minHeight && i < j) { i += 1 } 12 while (height[j] <= minHeight && i < j) { j -= 1 } 13 print(i, j) 14 } 15 return result 16 } 17 }
108ms
1 class Solution { 2 func maxArea(_ height: [Int]) -> Int { 3 if height.count == 0 { return 0 } 4 if height.count == 1 { return height[0] } 5 var head = 0 6 var tail = height.count - 1 7 let sortFunc: (((Int, Int), (Int, Int)) -> Bool) = { (ele1, ele2) -> Bool in 8 return ele1.1 < ele2.1 9 } 10 11 var maxArea = 0 12 for (idx, h) in height.enumerated().sorted(by: sortFunc) { 13 while h > height[head] { head += 1 } 14 while h > height[tail] { tail -= 1 } 15 16 let dToHead = idx - head 17 let dToTail = tail - idx 18 let area = max( dToHead * h, dToTail * h ) 19 if area > maxArea { 20 maxArea = area 21 } 22 } 23 24 return maxArea 25 } 26 }