-
Notifications
You must be signed in to change notification settings - Fork 0
Arai60/142 Linked List Cycle II #2
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,109 @@ | ||
# 問題概要 | ||
|
||
問題: 142. Linked List Cycle 2 | ||
|
||
https://hayapenguin.com/notes/LeetCode/142/LinkedListCycleTwo | ||
|
||
言語: Python | ||
|
||
# Step1 | ||
|
||
かかった時間:10min | ||
|
||
思考ログ: | ||
|
||
- set にどうやって append するの google 使う必要があった。 | ||
|
||
- set にするか dict にするか迷っていました。 | ||
|
||
```python | ||
from typing import Optional | ||
|
||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
nodes_passed_by_slow = 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. このコードでどのような処理を行いたかったか、順を追って説明してみていただけますか? 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. アルゴリズムの手順: nodes_passed_by_slow: slowポインタが通過したノードを記録するためのセット。 slowポインタは1つずつ進みます。 もしslowとfastが同じノードに到達した場合、サイクルが存在することになります。この場合、nodes_passed_by_slowとnodes_passed_by_fastの交差部分を求め、その最初のノードをサイクルの開始地点として返そうとしています。 fastがリストの終端に到達した場合、サイクルが存在しないと判断して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. ありがとうございます。おっしゃる通り、セットの交差部分が彼方らうサイクルの開始地点になるとは限らないと思います。問題点を自力で見つけることができたのは、とても素晴らしいと思います。 https://github.com/codgas/leetcode/pull/2/files#r1717036142 |
||
nodes_passed_by_fast = set() | ||
slow = fast = head | ||
while fast is not None and fast.next is not None: | ||
fast = fast.next.next | ||
nodes_passed_by_slow.add(slow) | ||
nodes_passed_by_fast.add(fast) | ||
if slow == fast: | ||
return next(iter(nodes_passed_by_slow & nodes_passed_by_fast)) | ||
slow = slow.next | ||
return None | ||
|
||
``` | ||
|
||
疑問点: | ||
|
||
- submit すると 8/17 成功、時間の問題ではないので、何かのミスです。 | ||
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 pointer と fast pointer を使用するところまで気づいたが、floyd の tortoise and hare アルゴリズムをきちんと知らなかったため、解決できませんでした。 | ||
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 | ||
|
||
かかった時間:5min | ||
|
||
思考ログ | ||
|
||
-Tortoise and hare の algorithm を使用 | ||
ref: https://leetcode.com/problems/linked-list-cycle-ii/solutions/3274329/clean-codes-full-explanation-floyd-s-cycle-finding-algorithm-c-java-python3/ | ||
|
||
```python | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
slow = fast = 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. floyd の tortoise and hare アルゴリズムでも解けるのですが、このアルゴリズムはソフトウェアエンジニアの常識には含まれていないように思います。おそらく想定解は、過去に辿ったノードを set に入れていき、今見ているノードと同じノードが set に含まれていたら、それを返す、というものだと思います。この方針の回答も書いてみていただけますか? |
||
while fast is not None and fast.next is not None: | ||
slow = slow.next | ||
fast = fast.next.next | ||
if fast == slow: | ||
slow = head | ||
while slow !=fast: | ||
slow = slow.next | ||
fast = fast.next | ||
return slow | ||
return None | ||
|
||
``` | ||
|
||
# Step3 | ||
|
||
かかった時間: 4 min | ||
|
||
上記を書き直してわかりやすくしました。 | ||
verbose になるように、変数名を工夫しました。 | ||
|
||
```python | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
slow = fast = head | ||
while fast is not None and fast.next is not None: | ||
slow = slow.next | ||
fast = fast.next.next | ||
if slow == fast: | ||
starter_pointer = head | ||
cycle_pointer = fast | ||
while starter_pointer != cycle_pointer: | ||
starter_pointer = starter_pointer.next | ||
cycle_pointer = cycle_pointer.next | ||
return starter_pointer | ||
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.
(odaさんのコメントと同じかもしれませんが、)一旦正解するまでをSTEP1とすると、他の方々と認識が揃って良さそうだと思いました。
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.
すみません、step 1 は自分が回答を見ずに書いたコードをそのまま書くだけと思っていました。このコードが全てのtest 通らなかったが、20分以上たったので、正解を見てみました。それこのコードに戻らなかったです。時間取られすぎるとあんまり効率悪いと思った追わなかったです。
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.
正解を見るのはいいですし、誤ったコードを残しておくのもよいことです。
ただ、気をつけて欲しいのは、コードが通ったことをゴールにしないことです。
https://discord.com/channels/1084280443945353267/1227462534211309589/1237419839795101858
https://github.com/h1rosaka/arai60/pull/4/files
このあたりを参考に何をしようとしているかを考えていただけると。