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.
问题:给定 n 个元素的数组 a1,a2..an,他们对应坐标中的 n 条线,第 i 条线的两端分别为坐标 (i, 0) 和 (i, ai)。求两根线,这两个线和 x 轴形成的容器能装最多的水。
这是一道直方图相关的题目,同样是直方图的题目还有:Trapping Rain Water 和 Largest Rectangle in Histogram。他们的解法有类似的地方,就是借助于递增元素以及对应的下标来计算。
- 分别找出从左往右递增元素 Ls ,以及从右往左的递增元素 Rs 。
- 用 Ls 的元素分别依次和 Rs 的元素组合形成容器,在所有结果中找到最大值就是原题目的解。
优化点:第二部做乘法时候,当 Ls[i] < Rs[k] 时候,Ls[i] 和 其他大于 Rs[k] 的组合可以不用再算,必然小于 Ls[i] 和 Rs[k] 。
1 int maxArea(vector<int>& height) { 2 3 if (height.size() < 2){ 4 return 0; 5 } 6 7 vector<int> idxAsceL; 8 9 idxAsceL.push_back(0); 10 11 for (int i = 1 ; i < height.size(); i++) { 12 13 if (height[i] > height[idxAsceL.back()]) { 14 idxAsceL.push_back(i); 15 } 16 } 17 18 vector<int> idxAsceR; 19 idxAsceR.push_back((int)height.size()-1); 20 21 for (int i = (int)height.size() - 2; i >= idxAsceL.back(); i--) { 22 if (height[i] > height[idxAsceR.back()]) { 23 idxAsceR.push_back(i); 24 } 25 } 26 27 int maxA = 0; 28 for (int i = 0 ; i < idxAsceL.size(); i++) { 29 for (int k = 0 ; k < idxAsceR.size(); k++) { 30 31 int l = idxAsceL[i]; 32 int r = idxAsceR[k]; 33 34 int h = min(height[l], height[r]); 35 36 int len = r - l; 37 maxA = max(maxA, h * len); 38 39 if (height[l] <= height[r]) { 40 break; 41 } 42 } 43 } 44 45 return maxA; 46 }