题目:
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.
题解:
第一种直观的解法,将高度和原始位置记录在一个struct Node里,对每一个Node按照其height升序排序。然后从排序后的最后一个元素,即height最大的元素开始,计算mostWater,当计算当前元素时,只需要看最左边和最右边的比它高的元素,取其中远的那一个元素。用start和end来记录已经计算过的元素中的当前最左位置和当前最右位置,每次计算前先更新start和end。因为需要排序,所以时间复杂度为O(nlgn)。
struct Node {
int index;
int height;
Node(int i, int h):index(i),height(h){}
Node(){}
bool operator < (const Node &t) const {
return height < t.height;
}
};
class Solution {
public:
int maxArea(vector<int> &height) {
if(height.size() <= 1)
return 0;
int mostWater = 0;
vector<Node> node(height.size());
for(int i = 0; i < height.size(); i++) {
node[i].index = i;
node[i].height = height[i];
}
sort(node.begin(), node.end());
int start = node[height.size()-1].index, end = start;
for(int j = height.size() - 2; j >= 0; j--) {
start = min(start, node[j].index);
end = max(end, node[j].index);
mostWater = max(mostWater, max(node[j].height * (node[j].index - start), node[j].height * (end - node[j].index)));
}
return mostWater;
}
};
第二种思路:两个指针,头和尾,计算当前mostWater,若头高,减尾指针,若尾高,加头指针。原因是只有这样才有可能增加储水量。时间复杂度O(n)。
C++;
class Solution {
public:
int maxArea(vector<int> &height) {
int length = height.size();
if(length <= 1)
return 0;
int start = 0, end = height.size()-1, mostWater = 0;
if(height[start] <= height[end]) {
mostWater = height[start] * (end - start);
start++;
}
else {
mostWater = height[end] * (end - start);
end--;
}
while(start < end) {
if(height[start] <= height[end]) {
mostWater = max(mostWater, height[start] * (end - start));
start++;
}
else {
mostWater = max(mostWater, height[end] * (end - start));
end--;
}
}
return mostWater;
}
};
java:
public class Solution {
public int maxArea(int[] height) {
if(height.length <= 1)
return 0;
int mostWater = 0, start = 0, end = height.length - 1;
while(start < end) {
mostWater = Math.max(mostWater, Math.min(height[start], height[end]) * (end-start));
if(height[start] <= height[end])
start++;
else
end--;
}
return mostWater;
}
}
Python:
class Solution:
# @return an integer
def maxArea(self, height):
if len(height) <= 1:
return 0
mostWater = 0
start = 0
end = len(height) - 1
while start < end:
mostWater = max(mostWater, min(height[start], height[end]) * (end - start))
if height[start] <= height[end]:
start += 1
else:
end -= 1
return mostWater