給定 n 個非負整數 height[0...n-1],代表坐標軸上各點的垂直線高度。找出兩條線,使其與 x 軸構成的容器能盛最多水。容器面積 = min(height[i], height[j]) * (j - i)。
int maxArea(vector& height) { int maxArea = 0; for (int i = 0; i < height.size(); ++i) { for (int j = i + 1; j < height.size(); ++j) { int area = (j - i) * min(height[i], height[j]); maxArea = max(maxArea, area); } } return maxArea; }
利用當前最大面積估算下一輪可能的最大寬度,跳過不可能超過的組合。但最壞情況仍為 O(N²)。
int maxArea(vector& height) { int left = 0, right = height.size() - 1; int maxArea = 0; while (left < right) { int area = (right - left) * min(height[left], height[right]); maxArea = max(maxArea, area); // 關鍵決策:移動較短的板 if (height[left] < height[right]) ++left; else --right; } return maxArea; }
數學證明:假設
height[left] < height[right]。當前面積受限於左板高度。若保持左板不動、移動右板:
- 寬度
(right-left)變小- 高度仍受限於左板(≤
height[left])- 面積必然 ≤ 當前面積
因此,移動右板不可能獲得更大面積。只有移動左板,才有機會遇到更高的板,從而突破高度限制。同理,右板較短時移動右板。
height = [1, 8, 6, 2, 5, 4, 8, 3, 7] 初始:left=0(1), right=8(7) → area=8×1=8 移動左板(較短) left=1(8), right=8(7) → area=7×7=49 ← 最大值 移動右板(較短) left=1(8), right=7(3) → area=6×3=18 ... 最終最大面積 = 49