From 47dd95075777a1b304545545c3c7b61051b198a6 Mon Sep 17 00:00:00 2001 From: tom4649 Date: Sat, 18 Apr 2026 17:49:33 +0900 Subject: [PATCH 1/2] 78. Subsets --- 78.Subsets/memo.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 78.Subsets/sol1.py | 8 +++++++ 78.Subsets/sol2.py | 14 ++++++++++++ 78.Subsets/sol3.py | 17 ++++++++++++++ 78.Subsets/sol4.py | 7 ++++++ 78.Subsets/sol5.py | 10 ++++++++ 6 files changed, 113 insertions(+) create mode 100644 78.Subsets/memo.md create mode 100644 78.Subsets/sol1.py create mode 100644 78.Subsets/sol2.py create mode 100644 78.Subsets/sol3.py create mode 100644 78.Subsets/sol4.py create mode 100644 78.Subsets/sol5.py diff --git a/78.Subsets/memo.md b/78.Subsets/memo.md new file mode 100644 index 0000000..b1e0113 --- /dev/null +++ b/78.Subsets/memo.md @@ -0,0 +1,57 @@ +# 78. Subsets + +https://leetcode.com/problems/subsets/description/ + +sol1.py: 何も考えないとbitmaskを思いついた。 +- 集合と聞いて +- 計算量 O(N*2^{N}) + +sol2.py: DFSで解く +- 計算量 O(2^{N}) + +sol3.py: backtrackを用いる +- 46. Permutationsで学んだ +- こちらを最初に自然に思いつくようにしたい + +## コメント集 +https://discord.com/channels/1084280443945353267/1200089668901937312/1222078986759311410 + +> 理想的な話をすると、関数は中を見なくても戻って来る物の想像がつくのが理想です。 + +自分は関数名や変数名が分かりづらいとの指摘が多いのでこころがけたい + +## 他の方のコード + +https://github.com/naoto-iwase/leetcode/pull/52/changes + +https://github.com/mamo3gr/arai60/blob/78_subsets/78_subsets/memo.md + +sol4.py: こんなに簡単に書けるのか + +sol5.py +勉強になったが、自分で書くのは無理だと判断 + +mapを用いるときに、関数定義のデフォルト引数が関数の定義時に定義されることを利用している + + + + +以下は関係ない話だが、思い出した話なので調べた + +上のvalueの渡し方は、評価戦略というよりかはデフォルト引数がいつ評価されるのかを決める話なので、少し違う話だった + + +https://docs.python.org/ja/3/reference/compound_stmts.html#function-definitions +「デフォルト引数値は関数定義が実行されるときに左から右へ評価されます。 これは、デフォルト引数の式は関数が定義されるときにただ一度だけ評価され、同じ "計算済みの" 値が呼び出しのたびに使用されることを意味します。」 + +=============================== + + + +pythonは「参照の値渡し」call-by-object: オブジェクトへの参照を、値としてコピーして渡す + +値呼び call by value: 関数に渡す前に実引数の式を一度だけ評価し、その結果の値(のコピー)を仮引数に束縛 + +名前呼び call by name: 実引数は すぐには評価しないで、関数の本体でその名前が使われるたびに、元の式をその都度評価 + +https://ja.wikipedia.org/wiki/%E8%A9%95%E4%BE%A1%E6%88%A6%E7%95%A5#:~:text=%E5%80%A4%E5%91%BC%E3%81%B3%EF%BC%88call%20by%20value%E3%80%81%E5%80%A4%E6%B8%A1%E3%81%97:%20pass%20by%20value%EF%BC%89%E3%81%AF%E3%80%81%E5%A4%9A%E3%81%8F%E3%81%AE%E8%A8%80%E8%AA%9E%E3%81%A7%E6%8E%A1%E7%94%A8%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E5%85%B8%E5%9E%8B%E7%9A%84%E3%81%AA%E8%A9%95%E4%BE%A1%E6%88%A6%E7%95%A5%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82%E5%80%A4%E5%91%BC%E3%81%B3%E3%81%A7%E3%81%AF%E3%80%81%E9%96%A2%E6%95%B0%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E3%81%AB%E3%81%82%E3%82%8B%E5%AE%9F%E5%BC%95%E6%95%B0%E3%82%92%E8%A9%95%E4%BE%A1%E3%81%97%E3%80%81%E9%96%A2%E6%95%B0%E3%81%AE%E4%BB%AE%E5%BC%95%E6%95%B0%E3%82%92%E6%96%B0%E3%81%97%E3%81%84%E5%A4%89%E6%95%B0%E3%81%A8%E3%81%97%E3%81%A6%E3%81%9D%E3%81%AE%E5%80%A4%E3%81%AB%E6%9D%9F%E7%B8%9B%E3%81%97%E3%80%81%E3%81%97%E3%81%8B%E3%82%8B%E5%BE%8C%E3%81%AB%E9%96%A2%E6%95%B0%E6%9C%AC%E4%BD%93%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%80%82%E9%96%A2%E6%95%B0%E3%81%AE%E4%B8%AD%E3%81%A7%E4%BB%AE%E5%BC%95%E6%95%B0%E3%81%A7%E3%81%82%E3%82%8B%E5%A4%89%E6%95%B0%E3%81%AB%E5%80%A4%E3%82%92%E4%BB%A3%E5%85%A5%E3%81%97%E3%81%A6%E3%82%82%E3%80%81%E3%81%9D%E3%82%8C%E3%81%AF%E5%B1%80%E6%89%80%E7%9A%84%E3%81%AA%E3%82%B3%E3%83%94%E3%83%BC%E3%81%B8%E3%81%AE%E4%BB%A3%E5%85%A5%E3%81%A7%E3%81%82%E3%82%8A%E3%80%81%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E3%81%9F%E5%81%B4%E3%81%AE%E5%A4%89%E6%95%B0%E3%81%AB%E3%81%AF%E5%BD%B1%E9%9F%BF&text=%E5%90%8D%E5%89%8D%E5%91%BC%E3%81%B3%EF%BC%88call%20by%20name%E3%80%81%E5%90%8D%E5%89%8D%E6%B8%A1%E3%81%97:%20pass%20by%20name%EF%BC%89%E3%81%A7%E3%81%AF%E3%80%81%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AF%E5%85%A8%E3%81%8F%E8%A9%95%E4%BE%A1%E3%81%95%E3%82%8C%E3%81%9A%E3%80%81%E6%8D%95%E7%8D%B2%E5%9B%9E%E9%81%BF%E7%BD%AE%E6%8F%9B%EF%BC%88Capture%2DAvoiding%20Substitution%EF%BC%89%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E9%96%A2%E6%95%B0%E6%9C%AC%E4%BD%93%E5%86%85%E3%81%AB%E7%9B%B4%E6%8E%A5%E7%BD%AE%E6%8F%9B%E3%81%95%E3%82%8C%E3%82%8B%E3%80%82%E5%BC%95%E6%95%B0%E3%81%8C%E3%81%9D%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AE%E8%A9%95%E4%BE%A1%E3%81%A7%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88%E3%80%81%E3%81%9D%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AF%E5%85%A8%E3%81%8F%E8%A9%95%E4%BE%A1%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E3%80%82%E5%BC%95%E6%95%B0%E3%81%8C%E8%A4%87%E6%95%B0%E5%9B%9E%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E5%A0%B4%E5%90%88%E3%80%81%E3%81%9D%E3%81%AE%E5%BA%A6%E3%81%AB%E5%86%8D%E8%A9%95%E4%BE%A1%E3%81%95%E3%82%8C%E3%82%8B%E3%80%82%20%E5%80%A4%E5%91%BC%E3%81%B3%E3%81%AF%E3%81%9D%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%8C%E5%85%A8%E3%81%8F%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%8F%E3%81%A8%E3%82%82%E5%BF%85%E3%81%9A%E8%A9%95%E4%BE%A1%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%80%81%E5%90%8D%E5%89%8D%E5%91%BC%E3%81%B3%E3%81%AE%E6%96%B9%E3%81%8C%E5%A5%BD%E3%81%BE%E3%81%97%E3%81%84%E3%81%A8%E3%81%99%E3%82%8B%E8%80%83%E3%81%88%E6%96%B9%E3%82%82%E3%81%82%E3%82%8B%E3%80%82 diff --git a/78.Subsets/sol1.py b/78.Subsets/sol1.py new file mode 100644 index 0000000..5022103 --- /dev/null +++ b/78.Subsets/sol1.py @@ -0,0 +1,8 @@ +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + subsets = [] + mask = (1 << len(nums)) - 1 + while mask >= 0: + subsets.append([num for i, num in enumerate(nums) if (mask >> i) & 1]) + mask -= 1 + return subsets diff --git a/78.Subsets/sol2.py b/78.Subsets/sol2.py new file mode 100644 index 0000000..7261dc0 --- /dev/null +++ b/78.Subsets/sol2.py @@ -0,0 +1,14 @@ +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + subsets = [] + frontier = [([], -1)] + + while frontier: + fixed, determined_idx = frontier.pop() + if determined_idx == len(nums) - 1: + subsets.append(fixed) + continue + frontier.append((fixed, determined_idx + 1)) + frontier.append((fixed + [nums[determined_idx + 1]], determined_idx + 1)) + + return subsets diff --git a/78.Subsets/sol3.py b/78.Subsets/sol3.py new file mode 100644 index 0000000..e9ec640 --- /dev/null +++ b/78.Subsets/sol3.py @@ -0,0 +1,17 @@ +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + subsets = [] + subset = [] + + def build_subset_after_index(index: int): + if index == len(nums): + subsets.append(subset.copy()) + return + subset.append(nums[index]) + build_subset_after_index(index + 1) + subset.pop() + build_subset_after_index(index + 1) + + build_subset_after_index(0) + + return subsets diff --git a/78.Subsets/sol4.py b/78.Subsets/sol4.py new file mode 100644 index 0000000..4a8ca2e --- /dev/null +++ b/78.Subsets/sol4.py @@ -0,0 +1,7 @@ +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + subsets = [[]] + for value in nums: + subsets.extend([subset + [value] for subset in subsets]) + + return subsets diff --git a/78.Subsets/sol5.py b/78.Subsets/sol5.py new file mode 100644 index 0000000..d45dbb5 --- /dev/null +++ b/78.Subsets/sol5.py @@ -0,0 +1,10 @@ +import itertools + + +class Solution: + def subsets(self, nums: list[int]) -> list[list[int]]: + results = [[]] + for value in nums: + a, b = itertools.tee(results) + results = itertools.chain(a, map(lambda s, v=value: s + [v], b)) + return list(results) From 367a5dfc7dfc7979fda88354ec3bb789a897d1fe Mon Sep 17 00:00:00 2001 From: tom4649 Date: Sun, 19 Apr 2026 05:48:07 +0900 Subject: [PATCH 2/2] Add suggested changes --- 78.Subsets/sol1_revised.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 78.Subsets/sol1_revised.py diff --git a/78.Subsets/sol1_revised.py b/78.Subsets/sol1_revised.py new file mode 100644 index 0000000..a8ac7da --- /dev/null +++ b/78.Subsets/sol1_revised.py @@ -0,0 +1,8 @@ +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + subsets = [] + mask = (1 << len(nums)) - 1 + while mask >= 0: + subsets.append([num for i, num in enumerate(nums) if (mask >> i) & 1 == 1]) + mask -= 1 + return subsets