From fc4f27a89e37fa05e56445347654cf34ff936f43 Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Mon, 29 Apr 2024 01:16:52 +0900 Subject: [PATCH 1/4] phase1 --- arai60/combination_sum/phase1.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 arai60/combination_sum/phase1.py diff --git a/arai60/combination_sum/phase1.py b/arai60/combination_sum/phase1.py new file mode 100644 index 0000000..92ed9b2 --- /dev/null +++ b/arai60/combination_sum/phase1.py @@ -0,0 +1,30 @@ +from typing import List + +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + # 再帰でも解けそうな気がするが, ひとまず単純な探索で解く + + stack = [[[], 0, target]] # [current_combination, current_candidate_index, current_target] + combinations = [] + while stack: + current_combination, current_candidate_index, current_target = stack.pop() + + if current_target == 0 and current_combination not in combinations: + combinations.append(current_combination) + continue + + if current_target - candidates[current_candidate_index] >= 0: + tmp_current_combination = current_combination.copy() # copy + tmp_current_combination.append(candidates[current_candidate_index]) + stack.append([tmp_current_combination, current_candidate_index, current_target - candidates[current_candidate_index]]) + + if current_candidate_index + 1 < len(candidates) and current_target - candidates[current_candidate_index+1] >= 0: + tmp_current_combination = current_combination.copy() # copy + tmp_current_combination.append(candidates[current_candidate_index+1]) + stack.append([tmp_current_combination, current_candidate_index+1, current_target - candidates[current_candidate_index+1]]) + + if current_candidate_index + 1 < len(candidates): + tmp_current_combination = current_combination.copy() # copy + stack.append([tmp_current_combination, current_candidate_index+1, current_target]) + + return combinations \ No newline at end of file From a418b19b5d51161c4a6e51e961e1fc4c6bdba499 Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Mon, 29 Apr 2024 02:09:22 +0900 Subject: [PATCH 2/4] phase2 --- arai60/combination_sum/phase2.py | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 arai60/combination_sum/phase2.py diff --git a/arai60/combination_sum/phase2.py b/arai60/combination_sum/phase2.py new file mode 100644 index 0000000..fa7b0dd --- /dev/null +++ b/arai60/combination_sum/phase2.py @@ -0,0 +1,66 @@ +""" +Reference +hayashi-ay: https://github.com/hayashi-ay/leetcode/pull/65/files +shining-ai: https://github.com/shining-ai/leetcode/pull/52/files +phase1の方法だと重複する場合が出てきた分だけ状態数も増えていることに気づいた。 +indexを増やすか今のindexが指す値を足すかで場合分けすれば十分であることがわかった。 +あと現在の足し込んだ値がtargetより大きいかで判断した方が多分素直な実装ですね(phase1でcurrent_target - candidates[current_candidate_index] >= 0と書いていた) + +あとは, +make_combination(index + 1, current_sum) +partial_combination.append(candidates[index]) +make_combination(index, current_sum + candidates[index]) +partial_combination.pop() +のような再帰を考えたことはなかったですね, これで再帰関数の引数から現在のcombinationを入れなくて済むんですね + +Mike0121: https://github.com/Mike0121/LeetCode/pull/1/files +時間計算量が分割数というらしい +""" + +# 再帰, whileの2通りで書く +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + combinations = [] + stack = [[[], 0, 0]] # current_combination, current_index, current_value + while stack: + current_combination, current_index, current_value = stack.pop() + if current_value == target: + combinations.append(current_combination) + continue + + if current_value > target: + continue + + if current_index >= len(candidates): + continue + + stack.append([current_combination, current_index + 1, current_value]) + added_current_combination = current_combination.copy() + added_current_combination.append(candidates[current_index]) + stack.append([added_current_combination, current_index, current_value + candidates[current_index]]) + + return combinations + +# 再帰 +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + combinations = [] + partial_combination = [] + def make_combinations(index: int, total: int) -> None: + if total == target: + combinations.append(partial_combination.copy()) + return + + if total > target: + return + + if index >= len(candidates): + return + + make_combinations(index + 1, total) + partial_combination.append(candidates[index]) + make_combinations(index, total + candidates[index]) + partial_combination.pop() + + make_combinations(0, 0) + return combinations \ No newline at end of file From 9fcb5c2cf084d1ebe5033c2f62395f62dfb4f788 Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Mon, 29 Apr 2024 02:09:31 +0900 Subject: [PATCH 3/4] phase3 --- arai60/combination_sum/phase3.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 arai60/combination_sum/phase3.py diff --git a/arai60/combination_sum/phase3.py b/arai60/combination_sum/phase3.py new file mode 100644 index 0000000..7dd255a --- /dev/null +++ b/arai60/combination_sum/phase3.py @@ -0,0 +1,23 @@ +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + # 書くのが安定しているwhileで書く + combinations = [] + stack = [[[], 0, 0]] # current_combination, current_index, current_value + while stack: + current_combination, current_index, current_value = stack.pop() + if current_value == target: + combinations.append(current_combination) + continue + + if current_value > target: + continue + + if current_index >= len(candidates): + continue + + stack.append([current_combination, current_index + 1, current_value]) + added_current_combination = current_combination.copy() + added_current_combination.append(candidates[current_index]) + stack.append([added_current_combination, current_index, current_value + candidates[current_index]]) + + return combinations \ No newline at end of file From 6473e99cd00c1892cb1a35147721c9bb103cc73f Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Mon, 29 Apr 2024 20:56:37 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Oda=E3=81=95=E3=82=93=E3=81=AE=E6=8C=87?= =?UTF-8?q?=E6=91=98=E3=82=92=E5=8F=97=E3=81=91=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arai60/combination_sum/phase4.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 arai60/combination_sum/phase4.py diff --git a/arai60/combination_sum/phase4.py b/arai60/combination_sum/phase4.py new file mode 100644 index 0000000..51224f4 --- /dev/null +++ b/arai60/combination_sum/phase4.py @@ -0,0 +1,20 @@ +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + combinations_of_sum_equals_target: List[List[int]] = [] # You will get the value of the target when all the elements of combinations are added together. + stack = [([], 0, 0)] + while stack: + combinations_so_far, index_to_append, sum_so_far = stack.pop() + # sum(combinations_so_far) == sum_so_far + if sum_so_far == target: + combinations_of_sum_equals_target.append(combinations_so_far) + continue + if sum_so_far > target: + continue + if index_to_append >= len(candidates): + continue + + stack.append((combinations_so_far, index_to_append + 1, sum_so_far)) + append_value = candidates[index_to_append] + stack.append((combinations_so_far + [append_value], index_to_append, sum_so_far + append_value)) + + return combinations_of_sum_equals_target \ No newline at end of file