diff --git a/11.ContainerWithMostWater/brute_force.cpp b/11.ContainerWithMostWater/brute_force.cpp new file mode 100644 index 0000000..fd5d4e5 --- /dev/null +++ b/11.ContainerWithMostWater/brute_force.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + int maxArea(vector& heights) { + int max_amount_water = -1; + for (int i = 0; i < heights.size(); i++) { + for (int j = 0; j < heights.size(); j++) { + int width = j - i; + int height = min(heights[i], heights[j]); + max_amount_water = max(max_amount_water, height * width); + } + } + return max_amount_water; + } +}; diff --git a/11.ContainerWithMostWater/memo.md b/11.ContainerWithMostWater/memo.md new file mode 100644 index 0000000..12ffb65 --- /dev/null +++ b/11.ContainerWithMostWater/memo.md @@ -0,0 +1,34 @@ +## ステップ1 +まず思いついたのはブルートフォースを使った解法 +2つのループを使って各区間の高さと幅を求めて水の量が最大になるか確認する +時間計算量はO(n^2)で入力データ数は10^5なので10^10となりC++でも1秒内に処理できない +brute_force.cppに実装。Leetcode上ではTLE + + +全ての区間を確認するのではなく、2つのポインターを用いて両サイドから幅を狭めつつ水の量を確認する +水量 = min(左側の高さ, 右側の高さ) × (右側のインデックス - 左側のインデックス) +左右両端のインデックスえを最初に選ぶと、幅は最も広い状態になる +低い方を動かす場合、幅は狭まるものの高さが上がる可能性があり、その場合には水量が増える +高い方を動かす場合、幅は狭まり高さは維持もしくは低くなる可能性がある + +低い方を狭まる方針をleftとrightがぶつかるまで行う +時間計算量O(n) +空間計算量O(1) +acceptまで7分 + +## ステップ2 +そもそもheightsがからの場合0を返却する処理を追加 +max_amount_waterの初期値を-1から0へ変更 + +## ステップ3 +**3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** + +## 他の解法 +Segment Treeで解く方法も存在する +そもそも名前しか知らないので調べるところから始めます。 +https://github.com/thonda28/leetcode/pull/16 + +2ポインターの解法がなぜうまくいくのか説明するのは難しい気がする +https://github.com/Jikuhara/LeetCode/pull/8 +## Discorなど + diff --git a/11.ContainerWithMostWater/step1.cpp b/11.ContainerWithMostWater/step1.cpp new file mode 100644 index 0000000..29d19bc --- /dev/null +++ b/11.ContainerWithMostWater/step1.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + int maxArea(vector& heights) { + int left = 0; + int right = heights.size() - 1; + int max_amount_water = -1; + while (left < right) { + int height = min(heights[left], heights[right]); + int width = right - left; + max_amount_water = max(max_amount_water, height * width); + if (heights[left] < heights[right]) { + left++; + } else { + right--; + } + } + return max_amount_water; + } +}; diff --git a/11.ContainerWithMostWater/step2.cpp b/11.ContainerWithMostWater/step2.cpp new file mode 100644 index 0000000..7a8438a --- /dev/null +++ b/11.ContainerWithMostWater/step2.cpp @@ -0,0 +1,23 @@ +class Solution { +public: + int maxArea(vector& heights) { + if (heights.empty()) { + return 0; + } + + int left = 0; + int right = heights.size() - 1; + int max_amount_water = 0; + while (left < right) { + int height = min(heights[left], heights[right]); + int width = right - left; + max_amount_water = max(max_amount_water, height * width); + if (heights[left] < heights[right]) { + left++; + } else { + right--; + } + } + return max_amount_water; + } +}; diff --git a/11.ContainerWithMostWater/step3.cpp b/11.ContainerWithMostWater/step3.cpp new file mode 100644 index 0000000..8948c61 --- /dev/null +++ b/11.ContainerWithMostWater/step3.cpp @@ -0,0 +1,22 @@ +class Solution { +public: + int maxArea(vector& heights) { + if (heights.empty()) { + return 0; + } + int left = 0; + int right = heights.size() - 1; + int max_amount_water = 0; + while (left < right) { + int height = min(heights[left], heights[right]); + int width = right - left; + max_amount_water = max(max_amount_water, height * width); + if (heights[left] < heights[right]) { + left++; + } else { + right--; + } + } + return max_amount_water; + } +};