Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions arai60/50-53_Greedy_Backtracking/52_39_Combination Sum/level_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Backtracking
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
def make_combination(remain, current, begin):
if remain == 0:
combinations.append(current[:])
return
if remain < 0:
return
for i in range(begin, len(candidates)):
current.append(candidates[i])
make_combination(remain - candidates[i], current, i)
current.pop()

combinations = []
make_combination(target, [], 0)
return combinations
17 changes: 17 additions & 0 deletions arai60/50-53_Greedy_Backtracking/52_39_Combination Sum/level_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Backtracking
# 再帰が深いので、stackで書き直した
class Solution:
def combinationSum(
self, candidates: List[int], target: int) -> List[List[int]]:
stack = [(target, [], 0)]
combinations = []
while stack:
before_remain, before_combination, begin = stack.pop()
for i in range(begin, len(candidates)):
remain = before_remain - candidates[i]
combination = before_combination + [candidates[i]]
if remain == 0:
combinations.append(combination)
elif 0 < remain:
stack.append((remain, combination, i))
return combinations
17 changes: 17 additions & 0 deletions arai60/50-53_Greedy_Backtracking/52_39_Combination Sum/level_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
sys.setrecursionlimit(2000)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これはどういう意図で追加していますか?どうして2000ですか?
(単なる興味です)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参考にしていた書籍が2000でやってたので、意図は全く無いです。

class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
def make_combinations(remain, combination, begin):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なんとなくbeginの順番がもう少し左側な気がします。重要な引数ほど左にいると良いのかなと思っていてremain, begin, combinationの順番の方が良いかなと思います。個人的にはbegin, remain, combinationですが、ここまでいくと好みの問題かもしれないです。

重要な引数ほど左にいると良いというのは、Pythonなど言語によっては引数のデフォルト値も取れることも関係していると思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

重要な引数ほど左にいると良い

このことを知らなかったので、順番は意識してませんでした。
ありがとうございます。

if remain < 0:
return
if remain == 0:
combinations.append(combination[:])
return
for i in range(begin, len(candidates)):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

begin == len(candidates)のときにrangeで空のシーケンスが変えるので結果的に終了しますが、明示的にチェックして上げても良いかなと思います。

combination.append(candidates[i])
make_combinations(remain - candidates[i], combination, i)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的には合計がtargetになるために必要な残りの値(remain)を管理するより、現在の合計を管理する方が素直かなと思いますが、好みの問題かもしれないです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

現在の合計だと次に何が来ればいいのかすぐ分からず、結局target-現在値を考えるのかと思いremainにしました。
確かに素直な実装じゃない気がしてきました。

combination.pop()

combinations = []
make_combinations(target, [], 0)
return combinations