From 3f9a7b41ecf9934225e52668f16be8b948bf740e Mon Sep 17 00:00:00 2001 From: Masakuni Date: Tue, 30 Dec 2025 12:45:21 +0900 Subject: [PATCH 1/3] step1 --- problems/2.add-two-numbers/memo.md | 46 +++++++++++++++++++++++++++ problems/2.add-two-numbers/step1.py | 48 +++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 problems/2.add-two-numbers/memo.md create mode 100644 problems/2.add-two-numbers/step1.py diff --git a/problems/2.add-two-numbers/memo.md b/problems/2.add-two-numbers/memo.md new file mode 100644 index 0000000..bc69014 --- /dev/null +++ b/problems/2.add-two-numbers/memo.md @@ -0,0 +1,46 @@ +## step1 +- エレガントな解法は思いつかなかった +- 2つとも数字に直して、足して一番大きい桁から新しく、連結リストを作る方法しか思いつかなかった +- 一回書いてみる +- 最後小さい桁からheadに入れないといけないので合計の数字を文字列にして逆順で取り出す +- headを特別に処理したくないので、前回勉強したdummy.nextを使ってみた + +``` + def addTwoNumbers( + self, l1: Optional[ListNode], l2: Optional[ListNode] + ) -> Optional[ListNode]: + l1_toal = 0 + l2_toal = 0 + + order = 0 + while l1: + l1_toal = l1_toal + l1.val * (10**order) + l1 = l1.next + order += 1 + order = 0 + + while l2: + l2_toal = l2_toal + l2.val * (10**order) + l2 = l2.next + order += 1 + + total = l1_toal + l2_toal + + total_string = str(total) + + dummy = ListNode() + node = dummy + for num in total_string[::-1]: + node.next = ListNode(int(num)) + node = node.next + + return dummy.next +``` + +- 解いた後再度確認すると最初に読んだ際に問題を誤読していて、小さい桁から値が入ってくるのであれば普通に足していけばいい気がしてきた +- 出た順に足していった + +## step2 + +## step3 + diff --git a/problems/2.add-two-numbers/step1.py b/problems/2.add-two-numbers/step1.py new file mode 100644 index 0000000..8d0bf43 --- /dev/null +++ b/problems/2.add-two-numbers/step1.py @@ -0,0 +1,48 @@ +# +# @lc app=leetcode id=2 lang=python3 +# +# [2] Add Two Numbers +# + +# @lc code=start +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def addTwoNumbers( + self, l1: Optional[ListNode], l2: Optional[ListNode] + ) -> Optional[ListNode]: + dummy = ListNode() + fixed_node = dummy + hasCarry = False + + while l1 or l2 or hasCarry: + # 繰り上げのみ + if l1 is None and l2 is None: + total = 1 + elif l1 is None: + total = l2.val + 1 if hasCarry else l2.val + elif l2 is None: + total = l1.val + 1 if hasCarry else l1.val + else: + total = l1.val + l2.val + 1 if hasCarry else l1.val + l2.val + + if total > 9: + hasCarry = True + total -= 10 + else: + hasCarry = False + + fixed_node.next = ListNode(total) + fixed_node = fixed_node.next + if l1: + l1 = l1.next + if l2: + l2 = l2.next + + return dummy.next + + +# @lc code=end From b4963fce21653bb1cda83b95b5d2d3dc202930e5 Mon Sep 17 00:00:00 2001 From: Masakuni Date: Tue, 30 Dec 2025 14:21:44 +0900 Subject: [PATCH 2/3] step2 --- problems/2.add-two-numbers/memo.md | 64 +++++++++++++++++++++++++++++ problems/2.add-two-numbers/step2.py | 40 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 problems/2.add-two-numbers/step2.py diff --git a/problems/2.add-two-numbers/memo.md b/problems/2.add-two-numbers/memo.md index bc69014..b097bc5 100644 --- a/problems/2.add-two-numbers/memo.md +++ b/problems/2.add-two-numbers/memo.md @@ -41,6 +41,70 @@ - 出た順に足していった ## step2 +- 変数名や処理も改善する部分がなさそうだと思ったので、他の人のコードを見てみる +- このくらいなら関数化しなくてもいいのかなと思った +- 関数化するなら合計の数字の繰り上げ処理のところとか、加算部分を関数化すると思う + +- https://github.com/tNita/arai60/pull/6/files +``` + [nits] + self に依存しないことを明示するために @staticmethod にする、というのもありそうです。 +``` + - 勉強になった。selfに依存しない場合@staticmethodと明記する。普段の業務でTSで開発しているとstaticとよく書くがpythonで開発していないためあまり気にしたことがなかったので気にしたい + - 計算量書くのは良いので真似する + +- https://github.com/Yoshiki-Iwasa/Arai60/pull/4 + - 私のコードではhasCarryとしてbooleanにしていたが、他の局面では繰り上がりは2以上になることがあるので今後の拡張性を意識してint型のcarryを使った方がいいかも? +- https://github.com/yus-yus/leetcode/pull/5/files/91f344d110d2dc8ce7982065314a25afec963cc9#r1944795971 + - `carry, digit = divmod(total, 10)` + - divmodという組み込み関数を知らなかった + - よくやる作業だし知らなくても関数名から意味がわかるので使っていきたい +- https://github.com/yus-yus/leetcode/pull/5 + - 下記のように書く + ``` + if not l1: l1 = ListNode(0) + if not l2: l2 = ListNode(0) + ``` + - 私の今のコードの場合whileの後の4行が不要になりスッキリするので採用する + - 他の人が見た場合でも伝わるはず +- https://github.com/SanakoMeine/leetcode/pull/6#discussion_r1901296375 + - この指摘はされないように気をつけたい + - 意図せず書いた場合はかなり印象悪くなりそう + - 数字や文字列は気にしなくてよくて、配列やobjectの場合は気にしているがある程度は慣れているので問題なさそうだが、LinkedListとかはかなり不安感ある +- https://github.com/mamo3gr/arai60/pull/5/files + - この方のコード見やすいのと他の方のコードについたコメントで気をつける点が全て反映されているような理想的なコードに見えた + - zipは見たことある,zip_longestは知らなかったが自分で書けるようになると今回のようなケースで便利 + - yieldは説明見てもあんまりピンとこないから怖くて使ってない + - 特にreturnや末尾で処理が止まらないところがいかつすぎる + - これ見たらイメージ湧いたかもしれない(https://qiita.com/shun_sakamoto/items/5f13fa96701ba3727dc0) +- これはyieldやzip_longestを使ってて上級者の書き方だと思った +``` +def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: + def generate_digits(l): + while l: + yield l.val + l = l.next + dummy = ListNode() + node = dummy + carry = 0 + for num1, num2 in zip_longest(generate_digits(l1), generate_digits(l2), fillvalue=0): + total = num1 + num2 + carry + node.next = ListNode(total % 10) + node = node.next + carry = total // 10 + if carry: + node.next = ListNode(carry) + return dummy.next +``` + +- 一旦下記を対応する + - 番兵 + - divmod + - carryをintにする + - 元の引数を変えない + +空間計算量: O(n) +時間計算量: O(n) ## step3 diff --git a/problems/2.add-two-numbers/step2.py b/problems/2.add-two-numbers/step2.py new file mode 100644 index 0000000..e76fd12 --- /dev/null +++ b/problems/2.add-two-numbers/step2.py @@ -0,0 +1,40 @@ +# +# @lc app=leetcode id=2 lang=python3 +# +# [2] Add Two Numbers +# + +# @lc code=start +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def addTwoNumbers( + self, l1: Optional[ListNode], l2: Optional[ListNode] + ) -> Optional[ListNode]: + dummy = ListNode() + fixed_node = dummy + + n1, n2 = l1, l2 + carry = 0 + + while n1 or n2 or carry: + v1 = n1.val if n1 else 0 + v2 = n2.val if n2 else 0 + + total = v1 + v2 + carry + carry, fixed_node_val = divmod(total, 10) + fixed_node.next = ListNode(fixed_node_val) + fixed_node = fixed_node.next + + if n1: + n1 = n1.next + if n2: + n2 = n2.next + + return dummy.next + + +# @lc code=end From 99425ec12a8b65717972597abf03a7d55ffb80e2 Mon Sep 17 00:00:00 2001 From: Masakuni Date: Tue, 30 Dec 2025 14:34:07 +0900 Subject: [PATCH 3/3] step3 --- problems/2.add-two-numbers/memo.md | 1 + problems/2.add-two-numbers/step3.py | 41 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 problems/2.add-two-numbers/step3.py diff --git a/problems/2.add-two-numbers/memo.md b/problems/2.add-two-numbers/memo.md index b097bc5..65e7003 100644 --- a/problems/2.add-two-numbers/memo.md +++ b/problems/2.add-two-numbers/memo.md @@ -107,4 +107,5 @@ def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optio 時間計算量: O(n) ## step3 +- 何回も消して書くと頭のリソースの使用量がだんだん小さくできている感覚がある diff --git a/problems/2.add-two-numbers/step3.py b/problems/2.add-two-numbers/step3.py new file mode 100644 index 0000000..0c5fd6f --- /dev/null +++ b/problems/2.add-two-numbers/step3.py @@ -0,0 +1,41 @@ +# +# @lc app=leetcode id=2 lang=python3 +# +# [2] Add Two Numbers +# + +# @lc code=start +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def addTwoNumbers( + self, l1: Optional[ListNode], l2: Optional[ListNode] + ) -> Optional[ListNode]: + dummy = ListNode() + fixed_node = dummy + carry = 0 + + n1, n2 = l1, l2 + + while n1 or n2 or carry: + val1 = n1.val if n1 else 0 + val2 = n2.val if n2 else 0 + + total = val1 + val2 + carry + carry, fixed_node_val = divmod(total, 10) + + fixed_node.next = ListNode(fixed_node_val) + fixed_node = fixed_node.next + + if n1: + n1 = n1.next + if n2: + n2 = n2.next + + return dummy.next + + +# @lc code=end