From 59a37a439cdf52f868c90d57f5d7e4431d11f3ab Mon Sep 17 00:00:00 2001 From: potrue <126231160+potrue@users.noreply.github.com> Date: Thu, 8 May 2025 23:54:38 +0900 Subject: [PATCH 1/2] 206. Reverse Linked List MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 問題: https://leetcode.com/problems/reverse-linked-list/description/ --- 206/206.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 206/206.md diff --git a/206/206.md b/206/206.md new file mode 100644 index 0000000..5936e41 --- /dev/null +++ b/206/206.md @@ -0,0 +1,85 @@ +## 何も見ずに解く + +```python +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + stack = [] + node = head + while node: + stack.append(node) + node = node.next + dummy = ListNode(None) + tail = dummy + while stack: + tail.next = stack.pop() + tail = tail.next + tail.next = None + return dummy.next +``` + +17分かかった(うち13分ぐらいは`tail.next = None`を入れていなかったことが原因のMemory Limit Exceededを解明している時間だった。。) + + +### Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both? + +recursiveっていうのはこういうことか? + +```python +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + def reverse_recursively(head): + if head and head.next: + tail = reverse_recursively(head.next) + tail.next = head + head.next = None + return head + node = head + while node and node.next: + node = node.next + reverse_recursively(head) + return node +``` + +### いろいろ調べてみる + +https://github.com/cheeseNA/leetcode/pull/11/files +https://github.com/hayashi-ay/leetcode/pull/13/files +https://github.com/5ky7/arai60/pull/8/files +https://github.com/sakupan102/arai60-practice/pull/8/files + +stackを使わない解法をしている方が多かった。 +おそらく最初の自分の(stackをつかった)解法は、問題文にある"iteratively"にも"recursively"にも分類されない方法っぽい。 + +再帰のコードは、新しいリストの(その時点の)末端を返すのではなく先頭を返すようにして、ポインタの書き換えは関数の返り値を利用せずにhead側から`head.next.next = head`のような感じでやってしまえば次のようによりシンプルになる。 + +```python +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + if not head or not head.next: + return head + new_head = self.reverseList(head.next) + head.next.next = head + head.next = None + return new_head +``` + +stackや再帰を使う方法は、stackは単純にスタックを積むので、再帰は関数の呼び出しスタックがたまるので空間計算量がO(n)になる。 +その点iterativeな方法は(新しく必要なのは)constantな空間計算量で済むみたいなので、こちらを最終コードにした。 +一時保存のための変数名は、nextとすると組み込み関数と被ってちょっと嫌、tmpやtempは何のことを指しているのかわからなくなりそう(実際に自分がこのように書かれたコードを最初に読んで理解に手間取ってしまった)なので、successorとしてみた。 + +### 最終コード + +```python +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + current = head + previous = None + while current: + successor = current.next + current.next = previous + previous = current + current = successor + return previous +``` + +(かかった時間: 1:32, 0:30, 0:38) From cefe3446c88b8e450683291ce2d90ebdba226d51 Mon Sep 17 00:00:00 2001 From: potrue <126231160+potrue@users.noreply.github.com> Date: Thu, 8 May 2025 23:56:41 +0900 Subject: [PATCH 2/2] Update 206.md --- 206/206.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/206/206.md b/206/206.md index 5936e41..f439f96 100644 --- a/206/206.md +++ b/206/206.md @@ -40,7 +40,7 @@ class Solution: return node ``` -### いろいろ調べてみる +## いろいろ調べてみる https://github.com/cheeseNA/leetcode/pull/11/files https://github.com/hayashi-ay/leetcode/pull/13/files @@ -67,7 +67,7 @@ stackや再帰を使う方法は、stackは単純にスタックを積むので その点iterativeな方法は(新しく必要なのは)constantな空間計算量で済むみたいなので、こちらを最終コードにした。 一時保存のための変数名は、nextとすると組み込み関数と被ってちょっと嫌、tmpやtempは何のことを指しているのかわからなくなりそう(実際に自分がこのように書かれたコードを最初に読んで理解に手間取ってしまった)なので、successorとしてみた。 -### 最終コード +## 最終コード ```python class Solution: