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
164 changes: 164 additions & 0 deletions 206.Reverse_Linked_List.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
1st.
stackにnodeをひとつづつ積んでいってすべて積み終わった後それを取り出せばいけると方針はすぐ立ったので実装にかかった。
順番に取り出して行くときに始まりがないといけないので一つだけ取り出したがこれが良かった科は分からない。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これは、番兵を立てるか、はじめの一つを特殊にするか、loop の中で分岐させるかでしょう。

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.

コメントありがとうございます。
始めの一つが.nextを変更されることがない特別なnodeであることに気づいたときに、
これらの選択肢がパッと出るように訓練したいです。

もっとシンプル実装があったかも。
dummy_nodeもresultの前にしたかったのでListNode(-1, result)としたがこれも読む人にとっては読みづらくなる原因かも。

```Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
stack = deque()

while node:
stack.append(node)
node = node.next

if not stack:
return None

result = stack.pop()
dummy_node = ListNode(-1, result)
Comment on lines +25 to +26
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

pop せずに、単に result = dummy_node はどうですか?

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 = dummy_nodeとしてresult.nextを変更する形で問題ないですね。
これで余計な場合分けがなくスッキリします。


while stack:
result.next = ListNode(stack.pop().val)
result = result.next

return dummy_node.next
```


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 reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
stack = deque()

while node:
stack.append(node)
node = node.next

dummy_node = ListNode()
result = dummy_node

while stack:
result.next = stack.pop()
result = result.next

return dummy_node.next
```
と書いてMemory Limited Exceededになっていた。これは最後にresultに追加したnodeのnextは変更されておらず一つ前にresultに入ったnodeを指しているのでその二つのnodeがお互いを指すループになっていて抜け出せないということ。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

はじめのループで .next をどのように引き継ぐかを意識してコードを書きましょう。

これの解決策としてnode.valだけ受け取って新しくListNodeをつくる方法で解いたが、問題となっているので最後のnodeのnextだけなのでこれをNoneにすればよい。
https://github.com/SanakoMeine/leetcode/pull/8
https://github.com/olsen-blue/Arai60/pull/7/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 reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
stack = deque()

while node:
stack.append(node)
node = node.next

dummy_node = ListNode()
result = dummy_node

while stack:
result.next = stack.pop()
result = result.next
result.next = None

return dummy_node.next
```

また、stackを用いない解法ひとつづつnodeのnextを付け替える方法を実装した。
こちらは空間計算量がO(1)なのでstackを用いた方法(O(n))より効率的
名前に関してはかなり悩んだが、odaさんの話のイメージから
old(順Liked List) → new(逆Linked list)にけて行くという意味を込めてnew, oldとした
これでどちらのLinkedListについて言っているのか分からなくなることはないと思う
https://discord.com/channels/1084280443945353267/1295357747545505833/1298524551592018003
```Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
new_next = None

while node:
old_next = node.next
node.next = new_next
new_next = node
node = old_next

return new_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 reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
stack = deque()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

listをstackとして扱うこともできます。
https://docs.python.org/3/tutorial/datastructures.html#using-lists-as-stacks


while node:
stack.append(node)
node = node.next

dummy_node = ListNode()
result = dummy_node
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

resultという変数名と、reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]という関数名+type hintから、resultが逆順にしたリストの何某かであることはわかるのですが、先頭なのか末尾なのか、はたまた別の何かなのか一見するとわかりにくいので、自分だったらreversed_tailとかつけるかなと思います。
それと関連して、dummy_nodeをdummy_reversed_headもしくはdummy_headとします。


while stack:
result.next = stack.pop()
result = result.next
result.next = None

return dummy_node.next
```

```Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
new_next = None

while node:
old_next = node.next
node.next = new_next
new_next = node
node = old_next

return new_next
Comment on lines +154 to +163
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

old, newという対比はわかりやすいですが、その二つで何が違うのか表せないので、自分ならoriginal, reversed (transformed)とするかと思います。
また、new_nextと変数名にnextをつけたのは、おそらくL159を意識しての事だと思いますが、ループを抜けた後まで通じやすい変数名ではないかもしれません。t0hsumi/leetcode#7 (comment)
以上を合わせて、自分なら、nodeをoriginal_head, new_nextをreversed_headとして、まだひっくり返していないリストの先頭と、もうひっくり返したリストの先頭を辿っていじる形にすると思います。

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.

コメントありがとうございます。
それが最適だと感じます。
コードの読み手から見たときにoriginal, reveresedが最も伝わりやすいですね。
上でも丁寧にコメントいただきありがとうございました。

```