1. 题目来源
2. 题目解析
方法一:双指针+贪心
经典的双指针加贪心。貌似也算不上贪心…不过证明的思路很像。
思路:
- 双指针
l
,r
各指向数组首尾 - 若
h[l] > h[r]
则r --
- 否则
l ++
可以通过反证法证明最优解一定能被遍历到。因为这两个指针一定是有其中一个到达最优解的一侧边界。那么另外一个指针就只能不断的向最优解另一侧靠近。因为,如果它不靠近,则表明在最优解一侧外还有比最优解还高的位置,那么和这个已经确定的最优解边界组成的面积岂不是更大?则矛盾。所以,该方法一定能遍历到最优解。且是 O ( n ) O(n) O(n) 的时间复杂度。很巧妙。
不知道单调栈能不能搞。画图确实很容易理解。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
代码:
class Solution {
public:
int maxArea(vector<int>& height) {
int res = 0;
for (int i = 0, j = height.size() - 1; i < j; ) {
res = max(res, min(height[i], height[j]) * (j - i)); // 一定是先更新,[1,1] hack样例
if (height[i] < height[j]) i ++;
else j --;
}
return res;
}
};
func maxArea(height []int) int {
n := len(height)
l, r := 0, n - 1
res := 0
for l < r {
res = max(res, min(height[l], height[r]) * (r - l))
if height[l] > height[r] {
r --
} else {
l ++
}
}
return res
}