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
33 changes: 33 additions & 0 deletions arai60/add-two-numbers/step1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'''
nextを作る位置を工夫しないと最後に余計なノードを作ってしまう
最後にc==1で繰り上がりを足さないといけないことに最初は気づいていたが、実装しているうちに忘れてしまっていた...
'''

class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
head = ListNode(-1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

head は、現在注目しているノード、リストの先端のノードを表すことが多いと思います。 dummy または sentinel はいかがでしょうか?

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を使おうと思います!

now = head

c = 0
while l1 and l2:
s = (l1.val + l2.val + c)%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.

% の両隣にスペースを空けたほうが良いと思います。

PEP8 では、演算子の優先順位の異なる複数の演算子を1 つの式で用いる場合、順位の低い演算子の両隣にスペースを空けることを推奨しています。
https://peps.python.org/pep-0008/#other-recommendations

Google Python Style Guide では、適切に判断してください、としています。
https://google.github.io/styleguide/pyguide.html#36-whitespace

PEP8 と Google Python Style Guide を一通り読まれることをお勧めします。

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.

ありがとうございます。
読みます🙏

c = (l1.val + l2.val + c)//10
now.next = ListNode(s)
now = now.next
l1 = l1.next
l2 = l2.next
while l1:
s = (l1.val + c)%10
c = (l1.val + c)//10
now.next = ListNode(s)
now = now.next
l1 = l1.next
while l2:
s = (l2.val + c)%10
c = (l2.val + c)//10
now.next = ListNode(s)
now = now.next
l2 = l2.next
if c == 1:
now.next = ListNode(1)
return head.next
53 changes: 53 additions & 0 deletions arai60/add-two-numbers/step2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'''
headという変数名は答えのheadを表していそうだから、fake_headに変える
nowもtailに変える
whileが多いからまとめる。
ただ、実際1つのループにまとめるのが困難なケースもある気がするので、そこは実装する前に考えたほうが良いかもしれない

口頭説明シミュレーション
まず、fake_headを作ります。
あとから後ろからノードをたどっていくのは大変なので、素早くheadを指せるポインタが欲しいからです。
次に、現在処理しているノードを表すtailを用意します。
また、l1とl2を足したときに繰り上がりが発生する可能性があるので、carryもここで用意しておきます。
l1かl2がNoneでないか、carryが1の間ループをします。
carryを入れる理由は、最後に繰り上がりだけ残った場合をループの中で処理したいからです。
そしてsum_valという変数は、それらを足した値とします。
carryを桁あふれ、つまりsum_valを10で割った商とします。
また、sum_valの10で割ったあまりをtailの次のノードの値とします。
そして、tail, l1, l2を次のステップへと進めます。
こうすることで、問題を解くことができました。
最後に桁上りしてl1とl2が終了する場合や、空のL1,l2を渡された場合にも対処できていることも確認できます。

Firstly, we create "fake_head".
This is because we want a pointer that can quickly point to the head.
Next, we prepare "tail" that represents the node currently being processed.
We also need to prepare "carry" because there is possibility of carry-over when l1 and l2 added.
We loop while l1 or l2 is not None or if carry is 1.
The reason for including "carry" is that we want to handle the case where only the carry remains in the loop.
The variable "sum_val" is the value obtained by adding them together.
Let carry be the overflow. In other words, it is the quotient of sum_val divided by 10.
And let sum_val's remainder divided by 10 be the value of the next node of tail.
Then we proceed to the next step for tail, l1, and l2.
In this way, we have solved the problem.
We can also confirm that we are able to deal with the case where l1 and l2 terminate after overflow or when an empty l1 and l2 are passed.
'''

class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
fake_head = ListNode(-1)
tail = fake_head

carry = 0
while l1 or l2 or carry:
sum_val = carry
if l1:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

sum_val += l1.val if l1 else 0 という書き方もあります。 l1 = l1.next if l1 else None と組み合わせると if 文が消せます。ただ、これで読みやすくなっているかと言われると、微妙なところです。

sum_val += l1.val
l1 = l1.next
if l2:
sum_val += l2.val
l2 = l2.next
carry = sum_val//10
tail.next = ListNode(sum_val%10)
tail = tail.next

return fake_head.next
27 changes: 27 additions & 0 deletions arai60/add-two-numbers/step3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'''
意識したこと
・fake_headを作る必要性
確認したこと
・各ポインタをちゃんと次のステップへ移動させているか?
・l1やl2が空のときにしっかりと動くか?
'''

class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
fake_head = ListNode(-1)
tail = fake_head

carry = 0
while l1 or l2 or carry:
sum_val = carry
if l1:
sum_val += l1.val
l1 = l1.next
if l2:
sum_val += l2.val
l2 = l2.next
carry = sum_val//10
tail.next = ListNode(sum_val%10)
tail = tail.next

return fake_head.next
24 changes: 24 additions & 0 deletions arai60/add-two-numbers/step4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'''
変数名をfake_head→dummy
%の両端にspace
'''

class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(-1)
tail = dummy

carry = 0
while l1 or l2 or carry:
sum_val = carry
if l1:
sum_val += l1.val
l1 = l1.next
if l2:
sum_val += l2.val
l2 = l2.next
carry = sum_val // 10
tail.next = ListNode(sum_val % 10)
tail = tail.next

return dummy.next