You are given an integer array height
of length n
. There are n
vertical lines drawn such that the two endpoints of the ith
line are (i, 0)
and (i, height[i])
.
Find two lines that together with the x-axis form a container, such that the container contains the most water.
Return the maximum amount of water a container can store.
Notice that you may not slant the container.
又回來解每日一題了,昨天有一題 hard 跟體積相關覺得複雜沒解出來,中斷連勝了嗚嗚
height
,表示有一連串的儲水量,需要在其中取兩點,再做出(i, 0)
, (i, height[i])
構成的邊n == height.length
2 <= n <= 105
0 <= height[i] <= 104
Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49
Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
7*7(第二和最後一位)寬度是7, 然後取比較小的高=7
實際情況跑不動
class Solution {
public:
int maxArea(vector<int>& height) {
int maxwater = 0;
int n = height.size() - 1;
for (int i = 0; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
int width = j - i;
int h = min(height[i], height[j]);
int area = width * h;
maxwater = max(maxwater, area);
}
}
return maxwater;
}
};
class Solution {
public:
int maxArea(vector<int>& height) {
int l = 0;
int r = height.size() - 1;
int maxwater = 0;
while(l < r){
int width = r - l; //從最大範圍的 x 開始檢查
int h = min(height[l], height[r]);
int area = width * h;
maxwater = max(maxwater, area);
if(height[l] < height[r]){
l++; //左邊的高度較矮,往右移動
}
else{
r--;
}
}
return maxwater;
}
};
[1, 8, 6, 2, 5, 4, 8, 3, 7]
↑ ↑
left=0 right=8
面積 = (8-0) × min(1,7) = 8×1 = 8
移動 left (因為 1 < 7)
[1, 8, 6, 2, 5, 4, 8, 3, 7]
↑ ↑
left=1 right=8
面積 = (8-1) × min(8,7) = 7×7 = 49 ✓ 最大值
**Maximum Tastiness of Candy Basket Medium**
**House Robber IV Medium**
此題的雙指針想法
特徵 | 滑動窗口 | 雙指針 |
---|---|---|
區間 | 必須連續 | 可以不連續 |
移動 | 單向(向右) | 相向/同向/任意 |
目的 | 維護窗口性質 | 搜索/配對 |
排序 | 不要求 | 常需要排序 |
HashMap | 經常需要 | 較少需要 |
複雜度 | O(n) | O(n) 或 O(n²) |
關鍵字 | 「連續」「子串」「子數組」 | 「排序」「兩數之和」「回文」 |
「最長」「最短」「包含」 | 「配對」「盛水」 |
[a, b, c, d, e, f, g]
[-----] ← 窗口向右滑動
[-----] ← 保持連續性
[-----]
特點: left 和 right 只能向右移動(單調性)
[a, b, c, d, e, f, g]
↑ ↑ ← 從兩端相向
↑ ↑ ← 任意移動
↑ ↑
特點: 指針可以相向、同向、跳躍移動
模板
int left = 0, right = 0;
while (right < n) {
// 擴大窗口
window.add(arr[right]);
right++;
// 收縮窗口
while (需要收縮) {
window.remove(arr[left]);
left++;
}
}
int left = 0, right = n - 1;
while (left < right) {
if (條件滿足) {
return 結果;
} else if (某條件) {
left++;
} else {
right--;
}
}
ps. 部分內容經 AI 協助整理