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.spa
這題O(n^2)的解法就是基本的暴力法。可是要想出O(n)的解法並不容易(實際上我就想不出來T_T),面試碰到這樣難度的新題估計就跪了。orm
雖然有點悲觀,可是解題的思路仍是有跡可循的。blog
container的面積由兩個因素組成,一個是高度,一個是寬度。get
咱們一樣採用的是「按序枚舉」的思路,高度是不肯定的變量,很差枚舉,可是寬度則是由1到n-1的肯定的量,能夠很方便的枚舉。it
此外,如同上題Candy,這種按序枚舉的思路也能夠是從左到右,從右往左等。io
在想到對寬度進行枚舉後,這種枚舉有兩種,一個是從小往大,另外一個是從大往小。form
若是咱們想從小往大枚舉,這種通常必須有dp的規律纔可以使解法更優,可是從本題來看,每個解都只與左右兩個index有關,並不包含子問題。因此從小往大的枚舉不可行。class
那麼從大往小枚舉,好比3,2,5,4,1。最大的寬度,就是從3到1,這時咱們能夠算出一個面積。當咱們縮小這個寬度,有兩種方法,可是實際上只有右區間縮小一個可能獲得最優解。爲何呢?由於每次對於左右邊界中較小的那一個,當前的寬度都是最寬的,也就是它能達到的最大面積了。變量
由此咱們能夠只往一個方向進行左右邊界的縮小,最終獲得的方法是O(n)的。
Code:
class Solution { public: int maxArea(vector<int> &height) { int n = height.size(); if(n < 2) return 0; int res = 0; int left = 0, right = n-1; while(left < right) { int tmp = min(height[left], height[right]) * (right - left); if(tmp > res) res = tmp; if(height[left] < height[right]) left++; else right--; } return res; } };