Leetcode 题目链接
思路
取首尾双指针和水量如下所示,设高度函数为
h
(
i
)
h(i)
h(i),在下图中
h
(
l
)
<
h
(
r
)
h(l) < h(r)
h(l)<h(r)。
观察以
l
l
l 为左边界所能构成的其他水量,与矮的右边界搭配结果如下。
与高的右边界搭配结果如下。
我们可以发现水量都会变小,即无法通过当前 l l l 获得更大的水量,可在记录水量后舍弃 l l l,使其右移。
如果初始 h ( l ) > h ( r ) h(l) > h(r) h(l)>h(r), 则镜像处理,令 r r r左移。
如果初始 h ( l ) = h ( r ) h(l) = h(r) h(l)=h(r),任意移动均可。
此后循环分析这个过程并移动指针即可。
严谨证明
假设初始 h ( l ) < h ( r ) h(l) < h(r) h(l)<h(r),当前可容纳的水量记为 c = ( r − l ) × h ( l ) c = (r - l) \times h(l) c=(r−l)×h(l)。
∀ i ∈ ( l , r ) \forall i \in (l, r) ∀i∈(l,r), i i i 和 l l l 作为边界对应的可容纳水量记为 c ′ = ( i − l ) × m i n { h ( i ) , h ( l ) } c' = (i - l) \times min\{h(i),\ h(l)\} c′=(i−l)×min{h(i), h(l)},其中:
- i − l < r − l i - l < r - l i−l<r−l
- m i n { h ( i ) , h ( l ) } ≤ h ( l ) min\{h(i),\ h(l)\} \leq h(l) min{h(i), h(l)}≤h(l)
故 c ′ < c c' < c c′<c,可在记录水量后舍弃 l l l,令 l l l 右移,因为无法通过 l l l 获得更大的水量。
余下分析同上。
代码
仅提供 java 代码。
class Solution {
public int maxArea(int[] height) {
int l = 0;
int r = height.length - 1;
int maxCap = 0; // 待返回的最大水量
while (l < r) {
int cap = (r - l) * Math.min(height[l], height[r]);
maxCap = Math.max(maxCap, cap);
if (height[l] < height[r]) {
l++;
} else {
r--;
}
}
return maxCap;
}
}
复杂度
时间:
Θ
(
n
)
\Theta(n)
Θ(n)
空间:
Θ
(
1
)
\Theta(1)
Θ(1)
推广
以下皆为个人所著,兼顾了职场面试和本硕阶段的学术考试。
- 附个人题解的双指针题单
- 图论入门
- 图论进阶
点赞关注不迷路,祝各位早日上岸,飞黄腾达!