diff --git a/206/206.md b/206/206.md new file mode 100644 index 0000000..f439f96 --- /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)