-
Notifications
You must be signed in to change notification settings - Fork 0
39. Combination Sum #56
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,33 @@ | ||
| class Solution { | ||
| public: | ||
| vector<vector<int>> combinationSum(vector<int>& candidates, int target) { | ||
| vector<vector<int>> all_combinations; | ||
| stack<CombinationAndTargetAndIndex> combination_state; | ||
|
|
||
| combination_state.push({{}, target, 0}); | ||
|
|
||
| while (!combination_state.empty()) { | ||
| auto [partial_combination, remain, start] = combination_state.top(); | ||
| combination_state.pop(); | ||
|
|
||
| if (remain == 0) { | ||
| all_combinations.push_back(partial_combination); | ||
| continue; | ||
| } | ||
| if (remain < 0) continue; | ||
| for (int i = start; i < candidates.size(); i++) { | ||
| vector<int> added_combination = partial_combination; | ||
| added_combination.push_back(candidates[i]); | ||
| combination_state.push({added_combination, remain - candidates[i], i}); | ||
| } | ||
| } | ||
|
Comment on lines
+18
to
+23
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. @oda またこちらの纏めは60問解き終わってからきちんと目を通そうと思います。 |
||
| return all_combinations; | ||
| } | ||
|
|
||
| private: | ||
| struct CombinationAndTargetAndIndex { | ||
| vector<int> combination; | ||
| int remain; | ||
| int index; | ||
|
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. どういうindexかの情報が個人的には欲しいかもです(appending_indexとか?) |
||
| }; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| ## ステップ1 | ||
| 再帰呼び出しごとに、数字を増やしていきその合計がtargetかどうかを確認する | ||
| 数字の重複OKなので、再帰呼び出し時のindexで少し詰まった | ||
|
|
||
| 引数が多いきもするが前2問のような考え方で解けた | ||
|
|
||
| ## ステップ2 | ||
| ・targetの数字から引いていって、残りが0か0を下回るのかで処理するように変更 | ||
| こうすればtargetとsumを引数に渡していたのをremainだけに減らすことが可能 | ||
| 参考 leetcodeの回答 | ||
| ・変数名変更 | ||
| all_candidates => all_combinations | ||
| partial_candidate => partial_combination | ||
| 候補って確かに曖昧でした。 | ||
| ・現時点でも合計がtarget以上なのかどうかを再帰呼び出しする前に移動 | ||
| remainに対して candidates[i] が大きすぎたら、それ以降の候補は試す必要がない | ||
|
|
||
| ・loop.cppを追加 | ||
| tuppleを使うよりstructを用いた | ||
| CombinationAndTargetAndIndexの中に部分組み合わせと残りの数字とインデックスを保持。 | ||
| 構造名がすごく微妙 | ||
|
|
||
| stackの変数名も微妙 | ||
|
|
||
| ## ステップ3 | ||
| **3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** | ||
|
|
||
| ## 他の解法 | ||
| >問題文や関数にあるものを命名に使うといい感じになる | ||
| ループで解いている。再帰の方法を形で覚えてしまっているので、再帰からループへの変換をしたら良さそう | ||
| https://github.com/nittoco/leetcode/pull/25 | ||
|
|
||
| >変化のある方を比較演算子の左側に置く方がわかりやすい | ||
| リーダブルコードを読み直そう | ||
| https://github.com/Mike0121/LeetCode/pull/1/commits/b2f5e21e45fc088fb86bdc1f66cb3f6cd4611027 | ||
|
|
||
| DPを使って解くことも可能 | ||
| >先にcandidatesをsortしておけば、total+candidates[i] > target となったときにi以降の要素を見る必要はないのでサボれる。 | ||
| なるほど再帰呼び出しの前に、targetと比較することで少し枝かりができるのですね。 | ||
| https://github.com/fhiyo/leetcode/pull/52 | ||
| https://github.com/Yoshiki-Iwasa/Arai60/pull/57 | ||
|
|
||
| ## Discorなど | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| class Solution { | ||
| public: | ||
| vector<vector<int>> combinationSum(vector<int>& candidates, int target) { | ||
| vector<vector<int>> all_candidates; | ||
| vector<int> partial_candidate; | ||
| GenerateCombinationToTarget(all_candidates, partial_candidate, candidates, target, 0, 0); | ||
| return all_candidates; | ||
| } | ||
|
|
||
| private: | ||
| void GenerateCombinationToTarget(vector<vector<int>>& all_candidates, vector<int>& partial_candidate, | ||
| const vector<int>& candidates, int target, int start, int sum) { | ||
| if (sum == target) { | ||
| all_candidates.push_back(partial_candidate); | ||
| return; | ||
| } | ||
| if (sum > target) { | ||
| return; | ||
| } | ||
| for (int i = start; i < candidates.size(); i++) { | ||
| partial_candidate.push_back(candidates[i]); | ||
| int partial_sum = 0; | ||
| for (int num : partial_candidate) { | ||
| partial_sum += num; | ||
| } | ||
|
Comment on lines
+22
to
+25
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. これ、sum + candidates[i] ですか?
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. @oda 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. あら、sum を更新せずに、新しい変数にするか引数に直接和を渡せば、引かなくてもいいのではないでしょうか。
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. @oda |
||
| GenerateCombinationToTarget(all_candidates, partial_candidate, candidates, target, i, partial_sum); | ||
| partial_candidate.pop_back(); | ||
| } | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| class Solution { | ||
| public: | ||
| vector<vector<int>> combinationSum(vector<int>& candidates, int target) { | ||
| vector<vector<int>> all_combinations; | ||
| vector<int> partial_combination; | ||
| sort(candidates.begin(), candidates.end()); | ||
| GenerateCombinationToTarget(all_combinations, partial_combination, candidates, target, 0); | ||
| return all_combinations; | ||
| } | ||
|
|
||
| private: | ||
| void GenerateCombinationToTarget(vector<vector<int>>& all_combinations, vector<int>& partial_combination, | ||
| const vector<int>& candidates, int remain, int start) { | ||
| if (remain == 0) { | ||
| all_combinations.push_back(partial_combination); | ||
| return; | ||
| } | ||
| for (int i = start; i < candidates.size(); i++) { | ||
| if (candidates[i] > remain) { | ||
| break; | ||
| } | ||
| partial_combination.push_back(candidates[i]); | ||
| GenerateCombinationToTarget(all_combinations, partial_combination, candidates, remain - candidates[i], i); | ||
| partial_combination.pop_back(); | ||
| } | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| class Solution { | ||
| public: | ||
| vector<vector<int>> combinationSum(vector<int>& candidates, int target) { | ||
| vector<vector<int>> all_combinations; | ||
| vector<int> partial_combination; | ||
| sort(candidates.begin(), candidates.end()); | ||
| GenerateCombinationToTarget(all_combinations, partial_combination, candidates, target, 0); | ||
| return all_combinations; | ||
| } | ||
|
|
||
| private: | ||
| void GenerateCombinationToTarget(vector<vector<int>>& all_combinations, vector<int>& partial_combination, | ||
| const vector<int>& candidates, int remain, int start) { | ||
| if (remain == 0) { | ||
| all_combinations.push_back(partial_combination); | ||
| return; | ||
| } | ||
| for (int i = start; i < candidates.size(); i++) { | ||
| if (candidates[i] > remain) { | ||
| break; | ||
| } | ||
| partial_combination.push_back(candidates[i]); | ||
| GenerateCombinationToTarget(all_combinations, partial_combination, candidates, remain - candidates[i], i); | ||
| partial_combination.pop_back(); | ||
| } | ||
| } | ||
| }; |
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.
targetとremainって意味的に違う気がして、こっちの名称はremainですかね?
また、C++のstructの名称の付け方の慣習が自分よくわかってないのですが、3つの要素をただandで繋げるのはデータ定義見ればわかるよ、と思ってしまいがちなのですが、どうなんでしょう、、、?
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.
@nittoco
レビューありがとうございます。
いっそのこと無理にstructを使わず、stackを3つ用いた方が分かりやすいですかね?
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.
うーん難しいですね、stackが3つなのもそれはそれで煩雑そうですし(はっきりしてなくてすみません)