-
Notifications
You must be signed in to change notification settings - Fork 0
Create 142LinkedListCicleII.md #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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
Linked list cycle II | ||
|
||
|
||
|
||
# 142. Linked list cycle II | ||
|
||
## すでに解いた方々(in:レビュー依頼 titleで検索) | ||
- https://github.com/atomina1/Arai60_review/pull/1/files | ||
- https://github.com/pineappleYogurt/leetCode/pull/3/files | ||
- https://github.com/t0hsumi/leetcode/pull/2/files | ||
- https://github.com/katataku/leetcode/pull/5/files | ||
- https://github.com/ichika0615/arai60/pull/2/files | ||
|
||
## Step 1 | ||
- ループが閉じる番号を探すなら順序を考慮するリストの方が良いのかなと思い、最初はリストで解いてみようとするも、計算時間オーバーでギブアップ | ||
- https://github.com/pineappleYogurt/leetCode/pull/3/files を拝見して、先の問題と同じようにsetで解いてnodeをreturnすれば良さそうと理解して書き直す | ||
- すでに解いた方々の回答と付き合わせてもそんなに悪くなさそう…?今の実力だとどんなコメントがつくか予想がつかない。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ここまでついたような細かい表現方法を整える方法の趣味趣向以外は問題ないでしょう。 |
||
|
||
```Python | ||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
visited_node = set() | ||
node = head | ||
|
||
while node and node.next is not None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 深く考えずに過去のPRを反映していたのに気づけました。ご指摘ありがとうございます。 |
||
if node in visited_node: | ||
return node | ||
else: | ||
visited_node.add(node) | ||
node = node.next | ||
Comment on lines
+28
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. elseで書かなくてもいいのではないでしょうか? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 実際step2を経てそちらの方がなんとなく自然だなと感じるようになりましたが、やはりそちらの方が一般的な感覚なんだなと確信が持てました。ご指摘ありがとうございます。 |
||
|
||
return None | ||
``` | ||
|
||
## Step 2 | ||
### Step2.1 | ||
- なぜ機能するのかさっぱりわからなかったフロイドのアルゴリズムについて小田さんが解説されていた:https://discord.com/channels/1084280443945353267/1246383603122966570/1252209488815984710 | ||
- 自分では絶対に思いつかないが、お絵描きしてみると言っていることは理解できた。時間が余った時にパズル的に聞かれることはあるとのことなので、おまけ気分で試しに書いてみる | ||
- 先人のコードとレビューを見ていると、フロイドのアルゴリズムを使った場合はどうも前の問題でも言及されていたwhileの見通しが問題が生じやすそう:https://discord.com/channels/1084280443945353267/1221030192609493053/1225674901445283860 Python独自の書き方というのがよく分かっていないので、1度試しに書いてみる(Whileとelseを並列させている部分がPython独自なのかな?) | ||
- が、たいしてif文の中が長くないので他の書き方でもよかった気がする。whileを2つ並べているのがまとめられそうでなんとなく気に食わない。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 確かにfast_nodeとslow_nodeがぶつかった場合に片方のポインタを最初の位置に戻してまた一つずつ動かせということなので、二つあるwhile文を一つにまとめることはできると思います。while文の中が長くなっちゃうので読めるようにする工夫はいるかもしれません。 |
||
- 先人の主語云々というのが取り入れられなかった気がするが、fast slowの順番の話なので、今回自分が書いたものとは関係ない…? https://github.com/katataku/leetcode/pull/5/files#r1845483049 | ||
|
||
```Python | ||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
fast_node = head | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. この関数内で扱われる対象がNodeであることは明らかであるため、わざわざnodeまで書かなくてもいいのではと思いましたがいかがでしょう? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なるほど、ありがとうございます |
||
slow_node = head | ||
|
||
# detect a collision point | ||
while fast_node and fast_node.next is not None: | ||
fast_node = fast_node.next.next | ||
slow_node = slow_node.next | ||
if fast_node is slow_node: | ||
break | ||
else: | ||
return None | ||
|
||
node_from_start = head | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 上同様ここもnodeであることは明らかで、使用する範囲も数行なのでstartなどでもいいかなと思いました(startだとちょっと汎用的すぎるかもですが) |
||
node_from_collision = fast_node | ||
|
||
# detect a intersection | ||
while node_from_start is not node_from_collision: | ||
node_from_start = node_from_start.next | ||
node_from_collision = node_from_collision.next | ||
else: | ||
return node_from_start | ||
``` | ||
|
||
## Step 3 | ||
とりあえずフロイドの方法のやり方自体は理解したが、実際に書くときはSetで書きたいなと思ったのでそちらで書いてみる。 | ||
時間を測りながら書いてみたらStep1のようにwhile->if->elseを使うのではなく、while->ifみたいな構造になっていた。 | ||
こっちの方がシンプルそうだなと感じてこちらを採用 | ||
1回目:4:59, 2回目:2:20, 3回目:2:20 | ||
```Python | ||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
node = head | ||
visited_node = set() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自分なら |
||
|
||
while node and node.next is not None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noneとの比較に、 また、ここの部分でも |
||
visited_node.add(node) | ||
node = node.next | ||
if node in visited_node: | ||
return node | ||
|
||
return None | ||
|
||
``` |
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.
in の判定が、中身を頭から全部舐めて確認しているので、数がたくさんに増えるにつれて遅くなっていくんですね。
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.
なるほど。「なんとなくこの辺のせいなのかな」くらいの感度しかなかったので、もう一度見返してみます。