Skip to content

2. Add Two Numbers#8

Open
atmaxstar wants to merge 1 commit into
mainfrom
2
Open

2. Add Two Numbers#8
atmaxstar wants to merge 1 commit into
mainfrom
2

Conversation

@atmaxstar
Copy link
Copy Markdown
Owner

問題:2. Add Two Numbers
言語: Python3


runner.val = val_sum % 10
carry_up = val_sum // 10
if l1 or l2 or carry_up > 0:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

l1 or l2 or carry_up > 0の重複を無くせそうでしょうか?

Copy link
Copy Markdown
Owner Author

@atmaxstar atmaxstar May 9, 2026

Choose a reason for hiding this comment

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

while True:
    val_sum = 0
    if l1:
        val_sum += l1.val
        l1 = l1.next
    if l2:
        val_sum += l2.val
        l2 = l2.next
    val_sum += carry
    runner.val = val_sum % 10
    carry = val_sum // 10

    if not (l1 or l2 or carry > 0):
        break

    runner.next = ListNode()
    runner = runner.next

これなら行けますが個人的にwhile Trueはエッジケースに引っかかった場合の永遠ループが怖くて実務では使いたくないですね。
ほかの方のrunner.nextに足した結果のノードを置いていく方式ならwhile文にl1 or l2 or carry > 0を置くだけで良さそうです。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

どっちも同値ではないですか?

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.

同値ですね。while文の外にcan_create_next_node = l1 or l2 or carry > 0
と置く感じでしょうか

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

あ、「コメントのコードも元のコードも振る舞いは同じではないでしょうか」という意味でした。

変数に置いても、結局2箇所で更新が必要そうですね。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

永遠ループではなく、無限ループではないですか?永久ループと呼ぶことはあると思いますが、永遠ループは聞いたことがなさそうです。振る舞いが同値だとすると、while Trueという見た目で、無限ループを心配するのは違和感があります。

https://e-words.jp/w/%E7%84%A1%E9%99%90%E3%83%AB%E3%83%BC%E3%83%97.html

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.

たしかに永遠ループ呼びは良くないですね。

while l1 or l2 or carry > 0に関してもl1, l2, carryが正しく更新されないと無限ループに入る可能性があるのでwhile Trueに対して無限ループに怯えるのは筋違いですね。ただ個人的にはwhile Trueよりwhile l1 or l2 or carry > 0の方が終了条件の可読性が良いので好きですね。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

同じ条件式を繰り返すのは、DRYに反するので、好ましくないかなと。while Trueの方なら、do whileに相当するので、すんなり読めそうです。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

次のループのノードを先に用意しておく必要がない、下のダミーノードの方法の方が総合的に優れているように感じました。

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.

なるほど、ノード関係の問題はdummyが役立ちそうな場面が多そうなので常に選択肢に持っておきます。

@@ -0,0 +1,121 @@
## step1:
まずl1, l2のheadからポインタを順番に線形探索していって、各ノードでvalを足してもし繰り上げがあればそれを次のノード同士での足し算で利用すれば実装できそうだと感じた。なので答えをanswer_headとしてrunnerにl1とl2の各ノードの足した結果を新しいノードとして順次生成してもらってそれを答えとする方針でいく。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

何らかの値を探索しているわけではないのに、線形探索と呼ぶのは誤用じゃないでしょうか?

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.

O(N)のものはなんでも線形探索って言ってました...
正しくは線形走査(linear scan)ですね

# self.next = next
class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
carry_up = 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

変数名は、carry_upであっていますか?

https://en.wikipedia.org/wiki/Carry_(arithmetic)

@@ -0,0 +1,121 @@
## step1:
まずl1, l2のheadからポインタを順番に線形探索していって、各ノードでvalを足してもし繰り上げがあればそれを次のノード同士での足し算で利用すれば実装できそうだと感じた。なので答えをanswer_headとしてrunnerにl1とl2の各ノードの足した結果を新しいノードとして順次生成してもらってそれを答えとする方針でいく。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

細かいですが、「繰り上げ」ではなく、「繰り上がり」ではないですか?

@@ -0,0 +1,121 @@
## step1:
まずl1, l2のheadからポインタを順番に線形探索していって、各ノードでvalを足してもし繰り上げがあればそれを次のノード同士での足し算で利用すれば実装できそうだと感じた。なので答えをanswer_headとしてrunnerにl1とl2の各ノードの足した結果を新しいノードとして順次生成してもらってそれを答えとする方針でいく。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

なので答えをanswer_headとしてrunnerにl1とl2の各ノードの足した結果を新しいノードとして順次生成してもらってそれを答えとする方針でいく。

コードを見ると、まずノードを作ってから、次のループで値を計算して代入しているので、説明と一致していなさそうですかね?

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.

たしかにこの説明はほかの人のdummyを使った解法で当てはまる説明ですね。
自分の解法はrunnerに値を代入する予定のノードを作成してそこにl1, l2, 繰り上がりの値を足した結果を代入する方針ですね。

val_sum += carry_up

runner.val = val_sum % 10
carry_up = val_sum // 10
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants