LeetCode 11-20題
阿新 • • 發佈:2021-12-22
本部落格記錄的是 LeetCode 11 到 20 題的題解
11. Container With Most Water
解決該問題,主要有兩種思路,
- 雙指標演算法
- 滑動區間內 + 雙指標
雙指標演算法
雙指標演算法特別簡單,具體操作如下:
我們使用指標 i, j分別指向 height 陣列的首尾兩端,並計算 i, j 所構成容器的面積
然後選擇高度小的指標指向內部,不斷獲得容器面積,更新 Res 答案。
演算法正確性的證明:
我們假設 res_i
, res_j
是我們最終產生最大容器的兩個高度,我們使用雙指標演算法時候,一定會有一個指標率先指向 res_i
或者是res_j
,在這裡,我們假設是 i
res_i
我們此時我們對 height[res_i] 和 height[res_j] 的情況進行討論,看
i,
j
是否可以同時指向 res_i
, res_j
第一種情況,height[res_i] < height[res_j]
指標 i不會一定,j不斷左移必定會指向res_j,主要是 height[j] 必須小於 height[res_i],否則 res_i 與 res_j便不會是最終解,與前提矛盾。
第二種情況,height[res_i] > height[res_j]
指標 i不會一定,j不斷左移必定會指向res_j,主要是 height[j] 必須小於 height[res_j],否則 res_i 與 res_j便不會是最終解,與前提矛盾。
那麼也一定小於height[res_i]
總而言之,當指標i指向了 res_i, res_j之外的高度,一定要小於 height[res_i], height[res_j]的最小值,那麼也就一定小於 height[res_i],也就會指標j最終指向res_j
c++
程式碼
class Solution { public: int maxArea(vector<int>& height) { int i = 0, j = height.size() - 1; int res = 0; while (i < j) { res = max(res, min(height[i], height[j]) * (j - i)); if (height[i] < height[j]) { i += 1; } else { j -= 1; } } return res; } };
python
程式碼
class Solution:
def maxArea(self, height: List[int]) -> int:
i, j = 0, len(height) - 1
res = 0
while i < j:
res = max(res, min(height[i], height[j]) * (j - i))
if height[i] < height[j]:
i += 1
else:
j -= 1
return res
折半查詢做法
c++
程式碼和註解:
/*
我們把 i 當做右邊界,而且是較小的右邊界,那麼我們只需要找到左側大於等於 height[i] 的靠左的部分即可
主要是根據貪心的原則 如果 height[j] >= height[j + 1] 那麼 j + 1根本就沒有什麼用處了,因為 j 這個位置比他高,還比他寬
*/
typedef pair<int, int> PII;
class Solution {
public:
int getMax(vector<int> v) {
vector<PII> a;
a.push_back(PII(v[0], 0));
int l, r, mid;
int res = 0;
for (int i = 1; i < v.size(); i ++ ) {
if (a.back().first < v[i]) {
a.push_back(PII(v[i], i));
} else {
// 在 a 遞增陣列中尋找大於等於 v[i] 的最小值
l = 0, r = a.size() - 1;
while (l < r) {
mid = l + r >> 1;
if (a[mid].first >= v[i]) {
r = mid;
} else {
l = mid + 1;
}
}
res = max(res, v[i] * (i - a[l].second));
}
}
return res;
}
int maxArea(vector<int>& height) {
return max(getMax(height), getMax(vector<int> (height.rbegin(), height.rend())));
}
};
python
程式碼和註解
class Solution:
def getMax(self, h):
res = 0
a = []
for i, x in enumerate(h):
if i == 0 or a[-1][0] < x:
a.append([x, i])
else:
l, r = 0, len(a)
while l < r:
mid = (l + r) // 2
if a[mid][0] >= x:
r = mid
else:
l = mid + 1
res = max(res, x * (i - a[l][1]))
return res
def maxArea(self, height: List[int]) -> int:
return max(self.getMax(height), self.getMax(height[::-1]))