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
99 changes: 99 additions & 0 deletions 206. Reverse Linked List/206. Reverse Linked List.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# 206. Reverse Linked List
## STEP1
- 何も見ずに解いてみる
```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]:
if head is None:
return None
node = head
prev_node = None
while True:
next_node = node.next
node.next = prev_node
prev_node = node
if next_node is None:
return node
node = next_node
```

#### memo
- まずはheadがNoneの場合を処理し、着目しているnodeと逆順に変換済みのprev_node、つなぎ換えの際にnode.nextを上書きするのでnext_nodeを変数として取っておくという方針とした。
- while文の条件とreturnする箇所がわかりやすいかは自信がない。

時間計算量
- O(N)
空間計算量
- O(1)

## STEP2
### プルリクやドキュメントを参照
- https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.x5w37bodndgj
- 再帰でも書ける。書いてみる。パターン1
```python
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
head, _ = self._reverse_list_helper(head)
return head

def _reverse_list_helper(self, node: Optional[ListNode]) -> tuple[Optional[ListNode], Optional[ListNode]]:
if node is None:
return None, None
if node.next is None:
return node, node
head, tail = self._reverse_list_helper(node.next)
tail.next = node
node.next = None
return head, node
```
- 再帰パターン2
```python
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
return self._reverse_list_helper(None, head)

def _reverse_list_helper(self, reversed_list: Optional[ListNode], node: Optional[ListNode]) -> Optional[ListNode]:
if node is None:
return reversed_list
node_to_be_checked = node.next
node.next = reversed_list
reversed_list = node
return self._reverse_list_helper(reversed_list, node_to_be_checked)
```
- prevという変数名については操作の順番から来ている。変数名を、意味からつけるか操作からつけるかわかりやすい方を採用する。
- STEP1をわかりやすく書き直す。STEP1では操作から変数名をつけたためprevという変数があった。これをsorted_headに変更した。
```python
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
checking_node = head
sorted_head = None
while checking_node is not None:
next_node = checking_node.next
checking_node.next = sorted_head
sorted_head = checking_node
checking_node = next_node
return sorted_head
```
- https://github.com/TORUS0818/leetcode/pull/9/files#r1598051541
- 考慮できていない観点であった。4行程度の処理なので問題ないと判断した。

## STEP3
### 3回ミスなく書く
```python
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
checking_node = head
sorted_head = None
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

sorted は reversed でしょうか。

特に問題ないと思います。

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.

reversedと書いたつもりでした。ご確認いただきありがとうございます。

while checking_node is not None:
next_node = checking_node.next
checking_node.next = sorted_head
sorted_head = checking_node
checking_node = next_node
return sorted_head
```
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

Choose a reason for hiding this comment

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

あとは付け替えていく方法とスタックで解く方法がありますね。
Ryotaro25/leetcode_first60#65 (comment)

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.

ありがとうございます。
stackを使う方法を書いてみました。(STEP2でstackのコードを読んではいました。)

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        stack = []
        while head is not None:
            stack.append(head)
            head = head.next
            stack[-1].next = None

        reversed_list_head = ListNode()
        reversed_list_tail = reversed_list_head
        while stack:
            reversed_list_tail.next = stack.pop()
            reversed_list_tail = reversed_list_tail.next
        return reversed_list_head.next

STEP3で書いたものが付け替えだと思っていたのですが、ほかにありましたっけ?新規に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.

すみません、こちら付け替えですね。
付け替え方にも3種類くらいあり勘違いしました!
https://discord.com/channels/1084280443945353267/1355246975309844550/1355898121460252784
今回は③ですかね。

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.

付け替え方で3種類もあるんですね。共有いただきありがとうございます。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

prevをなくしたことで何をやっているのかが明確になっていてとても良いと思うのですが、
sortedがどこから出てきたのか気になりました。reversed_headreliked_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.

ご指摘の通りsortedはおかしいですね。reversed_headが良さそうです。ありがとうございます。

2分,2分,2分で3回Accept