-
Notifications
You must be signed in to change notification settings - Fork 0
142. Linked List Cycle II.md #5
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,87 @@ | ||
|
||
URL: https://leetcode.com/problems/linked-list-cycle-ii/description/ | ||
|
||
# Step 1 | ||
|
||
- 実装時間: 5分 | ||
- 時間計算量: O(n) | ||
- 空間計算量: O(n) | ||
- フロイドのアルゴリズムでも解けると聞いた気がしたけど、理解してないので変数に記録する解放で解く。 | ||
|
||
```python | ||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
node = head | ||
nodes = set() | ||
while node is not None: | ||
if node in nodes: | ||
return node | ||
nodes.add(node) | ||
node = node.next | ||
return None | ||
``` | ||
|
||
# Step 2 | ||
|
||
- `nodes`という変数名がいまいち。 | ||
- すでに訪問済みであることを意味する`visited`にしよう。 | ||
- Javaのクラスやフィールド名には一般的に名詞(句)なので、`visited_nodes`になる。 | ||
- https://github.com/canisterism/leetcode/pull/3/files#r1688327425 | ||
|
||
- フロイドの循環検出の理解 | ||
|
||
- https://github.com/ichika0615/arai60/pull/2/files#r1807227628 | ||
- `かめがスタート地点に戻った時、うさぎはどこにいるでしょうか。実は、うさぎは衝突点にいます。なぜかというと、うさぎは倍速で走っているからです。スタート地点から衝突点を通って衝突点に到達するうさぎルートの長さは、スタートから衝突点に到達するかめルートの2倍だからです。` | ||
- ここちょっと混乱したので咀嚼してみる。 | ||
- `スタート〜合流点`の距離はn(亀の歩いた距離だから) | ||
- `スタート〜合流点`の距離は2n(うさぎの歩いた距離だから) | ||
- ということは、「うさぎのいる位置(2n)」から、うさぎがn歩戻ると「スタートからの距離が2n-nの場所」にいる。つまり「亀の歩いた距離n」と等しく、すなわちそこは合流点。 | ||
- setで解けることが常識の範囲 | ||
- https://github.com/codgas/leetcode/pull/2/files#r1717036142 | ||
|
||
なにはともあれ、フロイドの循環検出も実装してみる。 | ||
|
||
- ヘルパー関数を使った方がわかりやすい気がした。 | ||
|
||
```python | ||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
def find_meeting_point(head: Optional[ListNode]) -> Optional[ListNode]: | ||
fast = head | ||
slow = head | ||
meeting_node = 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. 使っていないですね。 |
||
while fast is not None and fast.next is not None: | ||
fast = fast.next.next | ||
slow = slow.next | ||
if slow == fast: | ||
return slow | ||
return None | ||
Comment on lines
+53
to
+58
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の条件分岐はfastを使っていてnodeの更新もfastからするなら、ifの条件の左辺をfastにしてreturnで返す値もfastにしないのかな~と思いました。 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 = find_meeting_point(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. ここでの変数名が 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. ありがとうございます。たしかに・・・ 他の方の書き方を見てみたので、まとめ:
|
||
if fast is None: | ||
return None | ||
slow = head | ||
while fast != slow: | ||
fast = fast.next | ||
slow = slow.next | ||
return fast | ||
``` | ||
|
||
|
||
# Step 3 | ||
|
||
- 時間計算量: O(n) | ||
- 空間計算量: O(n) | ||
|
||
```python | ||
class Solution: | ||
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
node = head | ||
visited = set() | ||
while node is not None: | ||
if node in visited: | ||
return node | ||
visited.add(node) | ||
node = node.next | ||
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.
構造の前後を入れ替えたいときに、
https://discord.com/channels/1084280443945353267/1221030192609493053/1225674901445283860
などの方法があります。