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.數組
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:this
Input: [1,8,6,2,5,4,8,3,7] Output: 49
真後悔本身之前沒有好好學數學,剛看到這道題,心裏是懵逼的, 大概能猜到首尾利用兩個遊標,來計算最大值。可是沒有想到的是:第一,最終兩個遊標須要相遇;第二,並不須要遍歷全部的狀況。spa
其實這個題,最暴力最直觀的想法就是遍歷全部的狀況,尋找最大值。3d
參考的解法,聰明之處,就是並不須要遍歷全部狀況,而是遍歷,咱們須要的值必定會存在的那片區域就行了。code
用兩個for循環實現的O(n^2)算法超時。苦想不出優化解,參考LeetCode討論區給出的O(n)算法,如下是該算法的證實和實現。 爲了提升效率。咱們須要在遍歷的過程當中剪去無用的狀況同時100%保證最大的值能在咱們餘下的狀況中獲取到。 在這個問題中,咱們初始化一左一右兩個遊標分別爲數組的端點。每一次向數組的中間移動值較小的遊標一步,直到兩個遊標相遇。這個過程當中,最大容量100%會被掃描過並獲取,如下是證實: 1、給定a1,a2,a3.....an做爲輸入,假設a10 和 a20是最大容量的狀況。咱們須要證實左遊標會到達a10,而且在這期間,右遊標能夠到達a20,所以核心問題變成:當左遊標在a10且右遊標在a21時,下一步的移動是右遊標指向a20。 2、由於咱們老是移動帶有較小值的遊標,若是a10>a21,咱們會移動把右遊標從a21移動到a20。假設a21>a10,則height[a10] x (20-10) < height[a10] x (21-10),與1中假設a10和a20是最大容量不符,所以必定有a10>a21。 3、綜上所述:左遊標會到達a10,而且在這期間,右遊標能夠到達a20,由此證實,該算法100%能獲取到最大值。
這個解法,就是必定不會錯過最大值。因此只有必定x線,纔會遇到更大值。那麼由此可推,只有每次移動更短的那根線,才能可能遇到最大值。orm
class Solution { public: int maxArea(vector<int>& height) { int size = height.size(); int max_area = 0; if (size < 2) return 0; int left = 0, right = size - 1; while(left < right) { max_area = max(max_area,(right-left)*min(height[left],height[right])); if (height[left]<height[right]) left++; else right--; } return max_area; } };