Skip to content
Open
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
209 changes: 209 additions & 0 deletions 2.Add_Two_Numbers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
1st.
方針としてはすぐにたって半加算器のようにsとcarryを持てばよいとわかったが、
```Python
while l1 or l2:
```
となっていたことで最後の桁の繰り上がりが考慮されていなかった
ここに気づけずに解答をみることとなった。
```Python
# 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(0)
s = dummy
carry = 0

while l1 or l2 or carry:
temp = 0
temp += carry
carry = 0
if l1:
temp += l1.val
l1 = l1.next
if l2:
temp += l2.val
l2 = l2.next

s.next = ListNode(temp % 10)
s = s.next
carry = temp // 10

return dummy.next
```
計算回数について見積もって置くと whileループが l1とl2のサイズの内大きい方+1(これは最後の桁あがりしだい)回る

2nd.
特に変数名に見づらさがあると感じたので修正した
```Python
# 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_node = ListNode()
result = dummy_node
carry = 0

while l1 or l2 or carry:
digit = carry
carry = 0

if l1 is not None:
digit += l1.val
l1 = l1.next
if l2 is not None:
digit += l2.val
l2 = l2.next

result.next = ListNode(digit % 10)
carry = digit // 10

result = result.next

return dummy_node.next
```

82.と同様にdummyを使わない方法でも実装してみた
```Python
# 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]:
first_val = l1.val + l2.val
carry = first_val // 10
head = ListNode(first_val % 10)
result = head
l1 = l1.next
l2 = l2.next

while l1 or l2 or carry:
digit = carry

if l1 is not None:
digit += l1.val
l1 = l1.next
if l2 is not None:
digit += l2.val
l2 = l2.next

result.next = ListNode(digit % 10)
carry = digit // 10
result = result.next

return head
```

digitはその桁の"値"という意味にしたかったので一度totalに入れてから、digitとcarryに入れなおすようにした
少し丁寧すぎる気もするが、可読性はあがったと思う

[参考にさせていただいたコード](https://github.com/katataku/leetcode/pull/4/files)

```Python
# 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_node = ListNode()
result = dummy_node
carry = 0

while carry != 0 or l1 is not None or l2 is not None:
total = carry

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if not l1:
    l1 = ListNode(0)
if not l2:
    l2 = ListNode(0)

という番兵を使う手があります。

ここの方法の応用です。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.cxy3cik6kyqx

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.

コメントありがとうございます。
Noneの時は0埋めするということですね。実装してみました。

total = l1.val + l2.val + carry

と書けるのが良いです。
新たにListNodeを追加してしまいますが、どのような使われ方をするか見て問題なさそうであれば変なリスクは取らずに可読性を優先するということですね。

if l1 is not None:
total += l1.val
l1 = l1.next
if l2 is not None:
total += l2.val
l2 = l2.next

digit = total % 10
carry = total // 10
Comment on lines +133 to +134

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, digit = divmod(total, 10)

これがいいとというより、選択肢の一つとしてご紹介です。

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.

コメントありがとうございます。
その組み込み関数は知りませんでした。勉強になります。
使いどころが限定されてそうですが今回の問題にはピッタリですね。

result.next = ListNode(digit)
result = result.next

return dummy_node.next
```

3rd.
解き方はかなりしっくり来ていたので読みやすいコードになるように丁寧に繰り返し書いた。
```Python
# 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_node = ListNode()
result = dummy_node
carry = 0

while l1 is not None or l2 is not None or carry != 0:
total = carry

if l1 is not None:
total += l1.val
l1 = l1.next
if l2 is not None:
total += l2.val
l2 = l2.next

digit = total % 10
carry = total // 10
result.next = ListNode(digit)
result = result.next

return dummy_node.next
```

4th.
番兵を使う書き方。
```Python
total = l1.val + l2.val + carry
```
と書けるため可読性があがる。
```Python
# 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_node = ListNode()
result = dummy_node
carry = 0

while l1 is not None or l2 is not None or carry != 0:
if not l1:
l1 = ListNode(0)
if not l2:
l2 = ListNode(0)

total = l1.val + l2.val + carry
digit = total % 10
carry = total // 10
result.next = ListNode(digit)
result = result.next

if l1:
l1 = l1.next
if l2:
l2 = l2.next

return dummy_node.next
```