-
Notifications
You must be signed in to change notification settings - Fork 0
152. Maximum Product Subarray #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| class Solution { | ||
| public: | ||
| int maxProduct(vector<int>& nums) { | ||
| if (nums.empty()) { | ||
| return 0; | ||
| } | ||
| int max_product = numeric_limits<int>::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; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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など | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| class Solution { | ||
| public: | ||
| int maxProduct(vector<int>& 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])); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Python のようにしたければ tie(a, b) = make_pair(b, a);というのが一応ありますが、素直に両方の変数を new_max, new_min とでも一度置いてから更新のほうが読みやすいでしょう。 |
||
| 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; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Solution { | ||
| public: | ||
| int maxProduct(vector<int>& 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; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Solution { | ||
| public: | ||
| int maxProduct(vector<int>& 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; | ||
| } | ||
| }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Apo-Matchbox |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Solution { | ||
| public: | ||
| int maxProduct(vector<int>& 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; | ||
| } | ||
| }; |

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
step 2 が私は愚直で気に入りました。このあたりで解いている人たちがいます。
https://discord.com/channels/1084280443945353267/1196498607977799853/1358736384604766238
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ありがとうございます。
小田さんの解法はstep2_2に近いので理解できました。
野田さんの解法は他のコメント、解説を読んでギリギリ理解できたような感覚です。きちんと言語化できないですが負の数が奇数になる場合を両サイドから見ていくことで避けていると理解しました。