diff --git a/152.MaximumProductSubarray/brute_force.cpp b/152.MaximumProductSubarray/brute_force.cpp new file mode 100644 index 0000000..8aa9d27 --- /dev/null +++ b/152.MaximumProductSubarray/brute_force.cpp @@ -0,0 +1,17 @@ +class Solution { +public: + int maxProduct(vector& nums) { + if (nums.empty()) { + return 0; + } + int max_product = numeric_limits::min(); + for (int i = 0; i < nums.size(); i++) { + int temp = 1; + for (int j = i; j < nums.size(); j++) { + temp *= nums[j]; + max_product = max(max_product, temp); + } + } + return max_product; + } +}; diff --git a/152.MaximumProductSubarray/memo.md b/152.MaximumProductSubarray/memo.md new file mode 100644 index 0000000..28d88ef --- /dev/null +++ b/152.MaximumProductSubarray/memo.md @@ -0,0 +1,36 @@ +## ステップ1 +まず思いついた解法はbrute forceで愚直に積を求める方法 +これだと時間計算量は、O(n^2)となる +nums.lengthは2 * 10 ^ 4なので4 * 10 ^ 8 C++だとギリギリ1秒ないに処理できそう + +各ステップで最大になるタイミングを追いかける +・あるnums[i]でリセットする場合(負の数を奇数個含む場合はnums[i]の方が大きくなることがある) +・正の数ばかりがsubarrayに含まれる場合 +・負の数偶数個含む場合 +単に正の数だけ追うのではなく負の数も追いかけると1ループで見つけられそう +時間計算量はO(n) +空間計算量はO(1) + +acceptまで12分 + +配列が空の場合にreturn 0とする。 +本当はありえない数字を返したかった。エラーメッセージを表示するなどでも良さそう。 + +## ステップ2 +step1の変数名が長いので、変更 + +maxとminの使い方変更 +initializer listsを使うことで複数の値でも使うことができる +https://cplusplus.com/reference/algorithm/max/ + +## ステップ3 +**3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** + +## 他の解法 +負の数が偶数個あると最大になりうる特性を活かして途中でswapすることで +自分のstep1で行った3パターンから2パターンへ比較回数を減らすことができる(step2_2で実装) +これは初見で思いつくことが難しそうなので愚直に比較したい +https://leetcode.com/problems/maximum-product-subarray/solutions/48230/possibly-simplest-solution-with-o-n-time-complexity/ + +## Discorなど + diff --git a/152.MaximumProductSubarray/step1.cpp b/152.MaximumProductSubarray/step1.cpp new file mode 100644 index 0000000..8924310 --- /dev/null +++ b/152.MaximumProductSubarray/step1.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + int maxProduct(vector& nums) { + if (nums.empty()) { + return 0; + } + int max_product = nums[0]; + int max_product_so_far = nums[0]; + int min_product_so_far = nums[0]; + for (int i = 1; i < nums.size(); i++) { + int temp_max_so_far = max(nums[i], max(max_product_so_far * nums[i], min_product_so_far * nums[i])); + min_product_so_far = min(nums[i], min(max_product_so_far * nums[i], min_product_so_far * nums[i])); + max_product_so_far = temp_max_so_far; + max_product = max(max_product, max_product_so_far); + } + + return max_product; + } +}; diff --git a/152.MaximumProductSubarray/step2.cpp b/152.MaximumProductSubarray/step2.cpp new file mode 100644 index 0000000..8041ed7 --- /dev/null +++ b/152.MaximumProductSubarray/step2.cpp @@ -0,0 +1,21 @@ +class Solution { +public: + int maxProduct(vector& nums) { + if (nums.empty()) { + return 0; + } + int max_product = nums[0]; + int current_max = nums[0]; + int current_min = nums[0]; + for (int i = 1; i < nums.size(); i++) { + // current_maxの数字は次の行で使うので一旦退避 + int temp = max({nums[i], current_max * nums[i], current_min * nums[i]}); + current_min = min({nums[i], current_max * nums[i], current_min * nums[i]}); + + current_max = temp; + max_product = max(max_product, current_max); + } + + return max_product; + } +}; diff --git a/152.MaximumProductSubarray/step2_2.cpp b/152.MaximumProductSubarray/step2_2.cpp new file mode 100644 index 0000000..870fda1 --- /dev/null +++ b/152.MaximumProductSubarray/step2_2.cpp @@ -0,0 +1,21 @@ +class Solution { +public: + int maxProduct(vector& nums) { + if (nums.empty()) { + return 0; + } + int max_product = nums[0]; + int max_product_so_far = nums[0]; + int min_product_so_far = nums[0]; + for (int i = 1; i < nums.size(); i++) { + if (nums[i] < 0) { + swap(max_product_so_far, min_product_so_far); + } + max_product_so_far = max(nums[i], max_product_so_far * nums[i]); + min_product_so_far = min(nums[i], min_product_so_far * nums[i]); + max_product = max(max_product, max_product_so_far); + } + + return max_product; + } +}; \ No newline at end of file diff --git a/152.MaximumProductSubarray/step3.cpp b/152.MaximumProductSubarray/step3.cpp new file mode 100644 index 0000000..e7ac00c --- /dev/null +++ b/152.MaximumProductSubarray/step3.cpp @@ -0,0 +1,21 @@ +class Solution { +public: + int maxProduct(vector& nums) { + if (nums.empty()) { + return 0; + } + + int max_product = nums[0]; + int current_max = nums[0]; + int current_min = nums[0]; + for (int i = 1; i < nums.size(); i++) { + int temp = max({nums[i], current_max * nums[i], current_min * nums[i]}); + current_min = min({nums[i], current_max * nums[i], current_min * nums[i]}); + + current_max = temp; + max_product = max(max_product, current_max); + } + + return max_product; + } +};