-
Notifications
You must be signed in to change notification settings - Fork 0
Combination Sum #13
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?
Combination Sum #13
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,51 @@ | ||
| """ | ||
| めちゃくちゃざっくり考えると、全体で候補は40! | ||
| が、実際はそうはならない。でもかなり大きくなる気がする | ||
| でも結局全通りは計算しないと解けないので、メタ読みだけど全探索はできるだろう。やるとしても枝狩り程度 | ||
| 再帰とかでやることを考える。重複を含まないために、自分より大きいやつしか考えなくてよい | ||
|
|
||
| 20m | ||
|
|
||
| メタ読みしてしまったのがよくないが、計算量の解析が難しい... | ||
| ざっくりした数で抑えて大丈夫なことを確認したい | ||
| 何か良い方法あれば教えてください>< | ||
| """ | ||
|
|
||
| class Solution: | ||
| def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: | ||
| combination_candidate = [] | ||
| combination_value_sum = 0 | ||
| target_combinations = [] | ||
| def count_target_combinations(index): | ||
| nonlocal combination_value_sum | ||
| for i in range(index, len(candidates)): | ||
| if combination_value_sum + candidates[i] > target: | ||
| continue | ||
| if combination_value_sum + candidates[i] == target: | ||
| target_combinations.append(list(combination_candidate) + [candidates[i]]) | ||
| continue | ||
| combination_candidate.append(candidates[i]) | ||
| combination_value_sum += candidates[i] | ||
| count_target_combinations(i) | ||
| combination_candidate.pop() | ||
| combination_value_sum -= candidates[i] | ||
| count_target_combinations(0) | ||
| return target_combinations | ||
|
|
||
| # stackでも書いてみる | ||
| # 実際再帰の深さによってどのようなデメリットがあるのかとかをちゃんと把握できていない気がする | ||
|
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. 再帰の深さは、 CPython 3.11.9 のデフォルトだと 1000 と設定されています。これを超えると例外が飛びます。 再帰の深さの上限は取得・設定できます。
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. こういう場合って、メモリを食べちゃうからスタックで実装したほうが良いんですかね? |
||
| class Solution: | ||
| def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: | ||
| target_combinations = [] | ||
| combination_stack = [([], 0, 0)] | ||
| while combination_stack: | ||
|
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. 変数名 "combination_stack"に関してですが、型名よりもcombination以外の値も入ってることを変数名に反映した方が良いのかなと思いました。3つ変数が入ると少し難しいですね。combination_sum_indexとかだとちょっと微妙ですね。良い案思いつかずすみません。
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. コメントありがとうございます。 |
||
| combination, value_sum, current_index = combination_stack.pop() | ||
| if value_sum == target: | ||
| target_combinations.append(combination) | ||
| continue | ||
| if value_sum > target: | ||
| continue | ||
|
|
||
| for i in range(current_index, len(candidates)): | ||
| combination_stack.append((combination + [candidates[i]], value_sum + candidates[i], i)) | ||
| return target_combinations | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| """ | ||
| combination_value_sumは、引数にしたほうが良い | ||
| countじゃなくてgenerateのほうが適切→makeのほうが適切かも? | ||
| 再帰する前に判定するよりも、再帰してからtargetに等しいかなどを判定したほうが、配列に追加済みなので簡単 | ||
|
|
||
| combination_value_sum、ちょっと名前が冗長な気がしつつ、短縮するアイデアがない | ||
| 再帰の深さにも注意。sys.setrecursionlimitとか | ||
| """ | ||
|
|
||
| class Solution: | ||
| def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: | ||
| combination = [] | ||
| target_combinations = [] | ||
| def make_target_combinations(index, combination_value_sum): | ||
| if combination_value_sum == target: | ||
| target_combinations.append(list(combination)) | ||
| return | ||
| if combination_value_sum > target: | ||
| return | ||
| for i in range(index, len(candidates)): | ||
| combination.append(candidates[i]) | ||
| make_target_combinations(i, combination_value_sum + candidates[i]) | ||
| combination.pop() | ||
| make_target_combinations(0, 0) | ||
| return target_combinations |
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 のように
combination_value_sumを関数の引数として渡したほうがきれいに見えました。また、変数名は sum_of_ の省略形の sum_ で始めるため、
sum_combination_valuesのほうが親善だと感じました。