1.Description
There is an array named height. height contains n elements. Each element means the length of a line. The beginning of the line is (length[n], 0) and all the lines are vertical to the x-axis. We need to find the biggest rectangular built by 2 of these lines. For example, we choose line height[a] and line height[b]. When height[a] is not equal to height[b], we should choose the smaller one to assure the rectangular exists.
2.Algorithm
Two pointer
3.Analysis
It is easy to have the idea of two pointers, but it takes me a lot of time to find out how to move these two pointers. I think the core of this moving strategy is similar to the idea of the greedy algorithm.
The area of a rectangular equals length times width. So if we want to maximize the area, we should maximize the length and the width. (I know, for a product, it is not that simple, but it doesn’t affect the conclusion in this problem.)
How can we make the length and the width bigger? First, look at the length. The length is easy to calculate. It’s the difference of the 2 indexes. If we want to maximize the length, we should choose the first element and the last. So we put 2 pointers point to each side.
For the first turn, it is easy to think. The area is (b-a) * min(height[a], height[b]). But what about the next turn?
Let’s think about the width. Suppose height[a] > height[b] (b>a). If we hold height[b], which means the left pointer will be moved one place to the right. If so, in next turn, the ideal area is height[b] * (b-a-1). But if we hold height[a], it is height[a] * (b-1-a).
Let’s compare height[a] * (b-1-a) and height[b] * (b-a-1). (b-1-a) equals to (b-a-1) and height[a] > height[b].
Therefore, each turn we should hold the pointer that points to the bigger element and move the other one.
To conclude, we do these things each turn until the two pointers encounter:
1.compare 2 elements and choose the smaller one as the width
2.calculate the current area
3.compare the current area with the current best answer and update the current best answer(if the current area is bigger than the current best answer)
4.hold the pointer that points to the bigger one and move the other one
When 2 pointers encounter, the algorithm is ended. Return the current best answer, which is now the global best answer.
class Solution {
public:
int maxArea(vector<int>& height) {
int right = height.size()-1, left = 0;
int ans = -1;
while(right != left){
ans = max((right - left)*min(height[right], height[left]), ans);
if(height[right] > height[left]) left++;
else right--;
}
return ans;
}
};
4.Complexity
Time complexity: O(n)
Space complexity: O(1)