Conversation
| node = head | ||
| while node and node.next: | ||
| node = node.next |
There was a problem hiding this comment.
ここ、もうちょっとなんとかしたいですね。
reverse_recursively がペアで返すなどの方法があると思います。
| stackを使わない解法をしている方が多かった。 | ||
| おそらく最初の自分の(stackをつかった)解法は、問題文にある"iteratively"にも"recursively"にも分類されない方法っぽい。 | ||
|
|
||
| 再帰のコードは、新しいリストの(その時点の)末端を返すのではなく先頭を返すようにして、ポインタの書き換えは関数の返り値を利用せずにhead側から`head.next.next = head`のような感じでやってしまえば次のようによりシンプルになる。 |
There was a problem hiding this comment.
head.next が最後になることを利用するのは、あんまりスマートではないと私は思います。
再帰にする方法もいくつかありそうです。コメント集を見ておいてください。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.x5w37bodndgj
There was a problem hiding this comment.
確かに関数がheadとtailを両方返すようにすれば再帰の幅も広がりそうですね!
ありがとうございます。
|
|
||
| stackや再帰を使う方法は、stackは単純にスタックを積むので、再帰は関数の呼び出しスタックがたまるので空間計算量がO(n)になる。 | ||
| その点iterativeな方法は(新しく必要なのは)constantな空間計算量で済むみたいなので、こちらを最終コードにした。 | ||
| 一時保存のための変数名は、nextとすると組み込み関数と被ってちょっと嫌、tmpやtempは何のことを指しているのかわからなくなりそう(実際に自分がこのように書かれたコードを最初に読んで理解に手間取ってしまった)なので、successorとしてみた。 |
There was a problem hiding this comment.
next_node としても良いと思います。また、previous, next がどの段階での前後関係か分かりにい場合もあるので、previous は reversed_head と書くこともできます。変数名を操作上からつけるパターンと意味からつけるパターンを使い分けられると良さそうです(どこかでコメントされていたと思いますが見つけられませんでした)。
There was a problem hiding this comment.
t0hsumi/leetcode#7 (comment)
こちらでしょうか。
たしかに意味を明示的にするなら、current_head_of_reversed, node, initial_successorなどとしても良いかもしれません。
意味的にしたほうがこのコードは全体として何をやっているかがコメントなしにもわかりやすくなりますね。
複雑なロジックになればなるほど意味的に名前を付けたほうがよくなりそうです。
ありがとうございます!
There was a problem hiding this comment.
おそらくそれです。操作の「意味と形式」でしたね。リンク共有ありがとうございます。
| previous = current | ||
| current = successor | ||
| return previous | ||
| ``` |
There was a problem hiding this comment.
上で指摘されていますが,
return previousはやや意図が伝わりにくいかもしれません.
successorは個人的にとてもわかりやすくていいなと思いました.
There was a problem hiding this comment.
自分も今見たらちょっとわかりにくいかもと思いました、、
変数名を変えるか、あるいはwhileの中に
if not successor: break
を入れてしまうのも手かもしれません。
問題:
https://leetcode.com/problems/reverse-linked-list/description/