Conversation
| @@ -0,0 +1,184 @@ | |||
| step1 | |||
| 訪れたノードのアドレスを記録しておき、同じアドレスが出てきたらサイクルがあると判断できると考えた。 | |||
There was a problem hiding this comment.
[fyi]
「正確にアドレスそのものなの?」と思ってドキュメントを見てみました。
https://docs.python.org/3.13/library/functions.html#id
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
CPython implementation detail: This is the address of the object in memory.
CPython ではそうで、他の処理系では当てはまらない場合もあるかもしれません。
| 割り算で余りを求めなくても、ビット演算で余りが分かるから。 | ||
| 2^13<15000<2^14だから2^14個スロットを用意する | ||
| 16バイト×2^14スロット=2^18バイト必要らしい | ||
| また、わざわざアドレスを調べなくても、変数名でインスタンスを参照できるので、id()はやめることにした。 |
There was a problem hiding this comment.
[fyi]
結局、内部では id() を使っていそうですね。
https://docs.python.org/3.13/reference/expressions.html#membership-test-operations
For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y).
https://docs.python.org/3.13/reference/expressions.html#is
The operators is and is not test for an object’s identity: x is y is true if and only if x and y are the same object. An Object’s identity is determined using the id() function.
There was a problem hiding this comment.
勉強になります。確かに、変数名で参照するときに、内部でどう動いているか気になるのが自然ですね。
| visited = set() | ||
|
|
||
| curr = head | ||
|
|
||
| while curr is not None: | ||
| if curr in visited: | ||
| return True | ||
|
|
||
| visited.add(curr) | ||
|
|
||
| curr = curr.next |
There was a problem hiding this comment.
趣味の範囲・個人の好みですが、空行が空きすぎに感じました。自分なら以下のようにします。
- ループの準備〜ループの開始行までは繋げる
ifの後は空けないelseのつもり
| visited = set() | |
| curr = head | |
| while curr is not None: | |
| if curr in visited: | |
| return True | |
| visited.add(curr) | |
| curr = curr.next | |
| visited = set() | |
| curr = head | |
| while curr is not None: | |
| if curr in visited: | |
| return True | |
| visited.add(curr) | |
| curr = curr.next |
| 2^13<15000<2^14だから2^14個スロットを用意する | ||
| 16バイト×2^14スロット=2^18バイト必要らしい | ||
| また、わざわざアドレスを調べなくても、変数名でインスタンスを参照できるので、id()はやめることにした。 | ||
| 現在見ているものを指すときはcurrが一般的な様なのでcheckではなく、currを使うようにした。 |
There was a problem hiding this comment.
おっしゃるように、curr のように単語を略記する場合は一般的な記法かどうかに注意することが重要そうです。
その上で、私が C++ で書いた際には curr ではなく current とし、さらにどのようなオブジェクトなのかがわかるように node_current としました。自分はPythonの一般的な記法に明るくないので参考程度に考えて欲しいですが、他のPythonで書いている方のコードも見てみると良いかもしれません。
| 自分はなんとなくリストで書いた。 | ||
| 他の人がsetで書いている理由がわからなかったので、geminiに聞いてみた。 | ||
| リストは要素の探索の際に線形探索を行うので、時間計算量がO(n^2)かかり、setではハッシュを使うので時間計算量はO(n)になると分かった。 | ||
| 空間計算量はどちらもO(n)だが、setでは衝突を防ぐためにリストより大きめにメモリを確保するらしい。 |
| return False | ||
| ``` | ||
|
|
||
| 解説の動画を見てみると知らない方法を使っていたのでそれも真似してみた。 |
There was a problem hiding this comment.
念のため確認させてください。なぜこの方法で上手くいくか説明できますか?
正解のコードを真似て、 Accept されることはできると思います。一方、現場では、なぜそれで正しく動くのかが分かったうえで書かないとまずいです。理由は、意図しない動作が起きた場合に修正が難しくなるためです。
There was a problem hiding this comment.
コメントありがとうございます。このコードは仕組みと上手くいく理由、時間計算量、空間計算量を理解したうえで書いています。
ご心配いただいた点は重要だと思うので、今後も理由まで説明できる形で実装することを意識します。
There was a problem hiding this comment.
(あ、まあ、重要なのは講師の目を気にすることではなく、感受性をあげて実際に他の人にコメントをすることなので、その他の人へのコメント能力への足しになると思うように行えばいいです。自分のコードに対して感じられないことはなかなか他人のコードに感じられないというのはそうかもしれません。)
| return False | ||
| ``` | ||
|
|
||
| 解説の動画を見てみると知らない方法を使っていたのでそれも真似してみた。 |
There was a problem hiding this comment.
こちらのコメントをご参照ください。
komdoroid/arai60#9 (comment)
この問題
https://leetcode.com/problems/linked-list-cycle/