-
Notifications
You must be signed in to change notification settings - Fork 0
142. Linked List Cycle #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
step2で解答を見た後に感じたコメントで、私はvalを参照していて、解答はノードを参照しているけどノードで比較する場合はvalとnextの両方を見ているのかという疑問を持ったが、調べる限りどうやらvalとnextを見ているのではなく、ListNodeオブジェクトのメモリアドレスを見ているようである。 |
chatgptに聞いてフロイドの循環アルゴリズム(別解)の仕組みを把握しました。 |
|
||
"""step2をやった。step1で私が書いたコードと非常に似ていると感じた。違いはset()を使用していること、headをそのまま使用しないで他の変数に置いているというところか。後の違いは私のコードはvalで比較をしているのに対して解答はノードで比較している点だ。この場合はvalとnextの両方が一致しているかみているということなのだろうか。 | ||
|
||
別解のフロイドの循環検出アルゴリズムは、今の段階で理解できていない。なんで、循環している時はfast.next.nextとslow.nextが同じになるという発送になるのだろうか""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AとBの二人がN歩で一周できる池の周りをぐるぐる周るとします。
Aは一歩ずつ、Bは二歩ずつ進むとします。
AとBを任意の地点に配置して、同じ方向にスタートさせると、毎回一歩ずつ二人の距離は相対的に縮まるので、いつか同じ場所にいる時がくるはずです。
一方で、循環がない場合はBさんが先に家に帰っちゃう(fast is Noneになる)ので二人が会うことはないです。
visited_node = set() | ||
current_node = head | ||
|
||
while current_node: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
変数に関してですね、参考にさせていただきます。
@@ -0,0 +1,73 @@ | |||
"""効率的な方法が特に思いつかなかったので愚直にやろうと思った。また、ListNodeの扱い方がよくわからなかったのでpythonのリストを用いた。一見良さそうなコードが書けたが、Nodeの中に同じ数字が入っているとダメであることに気づかずそこでsubmitも止まってしまった。(15分)""" | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
計算量の見積もり(時間、空間)もやっておくといいかもです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
計算量の見積もりは、計算時間を見積もるためのものなので、本当は時間まで見積もっておいたほうがいいです。ただ、そんなに高い精度は必要ではありません。
step2あたりで他の人のPRとdiscord上の関連議論を検索してみると良いと思います。 ご参考: |
lc141-1.py
Outdated
@@ -0,0 +1,12 @@ | |||
"""効率的な方法が特に思いつかなかったので愚直にやろうと思った。また、ListNodeの扱い方がよくわからなかったのでpythonのリストを用いた。一見良さそうなコードが書けたが、Nodeの中に同じ数字が入っているとダメであることに気づかずそこでsubmitも止まってしまった。(15分)""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
書こうとしているアルゴリズムの手続きを言語化すると良いと思います。
例えば、今回の問題なら、
ノードを頭から辿っていき、見つけたノードはリストに記録しておく、過去に見たことがあるノードだった場合はそこで打ち切り(循環あり)、最後まで到達したら循環はないと判断する
みたいな感じでしょうか。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
あとは、この思考の道中で考えたこともメモとして残しておくと、色々フィードバックが貰えると思います。
例えば、
以前ノードを見たかどうかをリストでチェックするようにしてるけど、効率が悪そう。
みたいな話とかですかね。
def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
head_list = [] | ||
while head: | ||
if head.val in head_list: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
step2以降はset()になっているので問題ないですが、この問題ではlistを使うかsetを使うかで顕著にスピード差が出ます。
Leetcode上で何度か実行すると、listで600ms、setで45sぐらいだと思います。
この理由は把握していますか?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
探索をするときの時間計算量の話で、setはhashで探索を、listは前から順に探索をしているからだと理解しています。ただ実は、step1~step3をやっている間はこれについて意識していなかったです。他の方のレビューを見てから調べたりして把握しました。
|
||
return False | ||
|
||
"""step2をやった。step1で私が書いたコードと非常に似ていると感じた。違いはset()を使用していること、headをそのまま使用しないで他の変数に置いているというところか。後の違いは私のコードはvalで比較をしているのに対して解答はノードで比較している点だ。この場合はvalとnextの両方が一致しているかみているということなのだろうか。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setの要素にできるか否かは、pythonの場合はその要素がhashableであるかどうかによります。
pythonの場合、objectを継承したクラスは特別な事をしない限りはhashableになり、すべての対象が保持しているidの値がそのままhashとして使われます。
したがって、特別な実装をしていない限りは、valとnextが一致していてもidが異なっていれば別物として扱われます。
current_node = head | ||
visited_node = set() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node, visitedでも十分かもしれません。
参考: https://github.com/h1rosaka/arai60/pull/2/files#r1688258262
問題: https://leetcode.com/problems/linked-list-cycle/description/
言語: Python
レビューをお願いします。