Conversation
nanae772
left a comment
There was a problem hiding this comment.
お疲れ様です、シンプルなループ、再帰、スタックなどいろいろな解き方をされていて良いなと思いました!
|
|
||
| ## 再帰について | ||
|
|
||
| 今回再帰でコード書いてみると通りはするけど、実際にノードの連結数に明記がないので不適。(LeetCodeの環境なら大丈夫なコードになってしまうから) |
There was a problem hiding this comment.
問題文の制約に
The number of nodes in the list is the range [0, 5000].
とありました。またLeetcodeではrecursionlimitが550000に設定されているようです。
ということであくまでこの問題の制約内かつLeetcode上であれば再帰を使っても大丈夫という判断ができそうです。
| # self.next = next | ||
| class Solution: | ||
| def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| if not head: |
There was a problem hiding this comment.
個人的にはif head is None:が自然かなという気がしました。
少し前に同様の議論があったのでそちらもご参考いただけると幸いです。
Kaichi-Irie/leetcode-python#20 (comment)
| stack.append(node) | ||
| node = node.next | ||
|
|
||
| tail = stack.pop() |
There was a problem hiding this comment.
tailより「逆順リストの先頭」である名前だとreturnに来た時に直感的に分かりやすいかな、と個人的に思いました
| node = tail | ||
|
|
||
| while stack: | ||
| node.next = stack.pop() | ||
| node = node.next | ||
| node.next = None |
There was a problem hiding this comment.
最初にstackから1つ取り出しておくのではなく、
- whileに入るたびに1つ取り出してnodeに代入
- node.nextをstackの一番上のノードに繋ぎかえる(無かったらNoneに繋ぐ)
とやって全てwhileの中に処理をまとめるというのもありかなと思いました。
(その場合は上の行はtail = stack[-1]とする必要があります)
| return head | ||
|
|
||
| new_head = self.reverseList(head.next) | ||
| head.next.next = head |
There was a problem hiding this comment.
head.next.nextは分かっていないと読み手がちょっと混乱する書き方でもあるかなと思うので、一旦head.nextを別の変数に代入してあげてもいいかもしれません。
| # self.next = next | ||
| class Solution: | ||
| def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| previous_node, current_node = None, head |
There was a problem hiding this comment.
previousは書き手の視点から見た名前ですが、最終的には逆順リストの先頭になるものですのでそれが分かる名前にしておくと伝わりやすいかもしれません。
| previous_node, current_node = None, head | ||
|
|
||
| while current_node: | ||
| tmp = current_node.next |
There was a problem hiding this comment.
スコープはかなり狭いので問題無いかなという気もしつつ、基本的にtmpという名前は情報が無いので少し避けたい気持ちがあります。
「反転していない残りの連結リストの先頭」なので自分なら単にrestとかhead_restとかにするかなと考えました。
| node.next = None | ||
|
|
||
| return tail | ||
|
|
There was a problem hiding this comment.
細かいところで恐縮なのですがいくつかのファイルの最後に余分な空行が入っているのが少し気になりました。
どのエディタを使われているかにもよるのですが、例えばVS CodeであればTrim Final Newlinesという設定をONにしておくとファイル保存時に自動的に消してくれたりします。そのような設定をしてみてもいいかもしれません。
| - スタック | ||
| があることを知った。 | ||
|
|
||
| ## 再帰について |
There was a problem hiding this comment.
再帰の書き方については2種類あるようなのでそちらも見ておくと勉強になるかもしれません
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.x5w37bodndgj
Reverse Linked List/memo.md
Outdated
|
|
||
| 今回再帰でコード書いてみると通りはするけど、実際にノードの連結数に明記がないので不適。(LeetCodeの環境なら大丈夫なコードになってしまうから) | ||
|
|
||
| 時間計算量はO(N), 空間計算量はO(1) |
There was a problem hiding this comment.
再帰深さが最大になった場合その分スタックフレームに積まれて空間計算量はO(N)になる気がします。
There was a problem hiding this comment.
おっしゃるとおりですね、、!
ありがとうございます!
| if not head: | ||
| return None | ||
|
|
||
| new_head = head |
There was a problem hiding this comment.
この部分の役割がぴんとこず、上のbase caseにまとめたほうがすっきりしそうだなと思いましたが実際step3ではそのようにされていてそちらのほうが意図が取りやすかったです。
問題: https://leetcode.com/problems/reverse-linked-list/description/