-
Notifications
You must be signed in to change notification settings - Fork 0
Create 142. Linked List Cycle II.md #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,188 @@ | ||
| # step1 | ||
| 問題は142. Linked List Cycleとほとんど同じ?outputが具体的なnode番号にすればよい? | ||
|
|
||
| 前回のコード | ||
| ```python | ||
| class Solution: | ||
| def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
| visited = set() | ||
| node = head | ||
| while node is not None: | ||
| if node in visited: | ||
| return True | ||
| visited.add(node) | ||
| node = node.next | ||
| return False | ||
| ``` | ||
|
|
||
| if node in visitedのところで何番目の値かを見る方法があるかな? | ||
| (そういえばsetって重複が許されないからテストケースによっては上手くいかなそう) | ||
|
|
||
| https://docs.python.org/ja/3/library/stdtypes.html#set | ||
|
|
||
| 使えそうなメソッドはpopぐらい?1つずつ出して確認する方法? | ||
| >https://docs.python.org/ja/3/library/stdtypes.html#set | ||
| >オブジェクトの順序なしコレクションです。 | ||
|
|
||
| 順序のある配列かリストを使うのかな? | ||
|
|
||
| 配列とリストの違いがあいまいなので調べる。 | ||
| https://docs.python.org/ja/3/library/stdtypes.html#lists | ||
|
|
||
| 配列arrayは標準ライブラリをimportして使うもの。 | ||
|
|
||
| タプル:イミュータブルなリスト(https://docs.python.org/ja/3/library/stdtypes.html#tuples) | ||
|
|
||
| 辞書:key valueでの保存 | ||
|
|
||
| 処理イメージ | ||
|
|
||
| - visitedのリストを作る | ||
| - headの値でループ | ||
| - ループの条件はNoneが来るまで。 | ||
| - if node in visiitedのとき | ||
| - ループでvisited[i] == node になる iの値を探す。 | ||
| - visitedが3,2,0,-4 でnodeが2のとき、i=1 | ||
| - retunr tail connects to node index i | ||
| - ifの条件に入らなかったらnode = node.nextとvisited.append(node) | ||
|
|
||
| ```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]: | ||
| visited = [] | ||
| node = head | ||
| while node is not None: | ||
| if node in visited: | ||
| for i in visited: | ||
| if visited[i] == node: | ||
| print("tail connects to node index" + i) | ||
| node = node.next | ||
| visited.append(node) | ||
| ``` | ||
| ``` | ||
| TypeError: list indices must be integers or slices, not ListNode | ||
| ~~~~~~~^^^ | ||
| if visited[i] == node: | ||
| Line 14 in detectCycle (Solution.py) | ||
| result = Solution().detectCycle(head) | ||
| Line 44 in _driver (Solution.py) | ||
| ~~~~~~~^^ | ||
| _driver() | ||
| Line 71 in <module> (Solution.py) | ||
| ``` | ||
|
|
||
| returnでprintを返すのかな? | ||
|
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. return で print を返すという表現に違和感を感じました。 参考までに、関数の return 文で、 print 関数を返すとこのようになります。
Owner
Author
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. ありがとうございます、問題の理解不足で変な操作をしようとしていました。 |
||
| →問題文読んだらサイクルのbeginsを返すだった。サイクルの開始はif node in visitedの時点でのnode? | ||
| ```python | ||
| class Solution: | ||
| def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| visited = [] | ||
| node = head | ||
| while node is not None: | ||
| if node in visited: | ||
| return node | ||
| # for i in range(len(visited)): | ||
| # print(i) | ||
| # if visited[i] == node: | ||
| # return print("tail connects to node index " + str(i)) | ||
| visited.append(node) | ||
| node = node.next | ||
| ``` | ||
| 自分は問題文の読み違いや取り違いが多い気がする。 | ||
|
|
||
| # step2 | ||
|
|
||
| 他の人のPRなど見てみる. | ||
|
|
||
| https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.jfs03xpyyrfl | ||
|
|
||
|
|
||
| https://github.com/Nbotter/leetcode-easy-swe-practice/pull/12 | ||
|
|
||
| - is not None と ==について | ||
|
|
||
| →https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.45ot5ov2xt6j | ||
|
|
||
| https://github.com/komdoroid/arai60/pull/9/changes#r2609582607 | ||
|
|
||
| https://discord.com/channels/1084280443945353267/1307605446538039337/1309221770418454531 | ||
|
|
||
| >速度の話をすると、Python は C などの50倍くらい遅いので本当に速くしたいならば言語を変えるのも選択の一つです。 | ||
| 速度的にはisのほうがわずかに早いらしい。 | ||
|
|
||
| - return false入れてないけどいいのか? | ||
|
|
||
| →AI回答「Pythonはwhileを抜けた後、return None を省略しても暗黙的に None を返すので動きます。ただし明示的に書くほうが読みやすいです。」 | ||
|
|
||
| - nodeに代入する理由は? | ||
|
|
||
| →AI回答「node = head に代入する理由head を直接動かすと、元のリストの先頭への参照を失うためです。node という別変数を使って走査します。」 | ||
|
|
||
| →まだ参照とかをちゃんと理解しきれていなさそう。node = headのタイミングではnodeとheadは同じオブジェクト。node = node.nextとしたタイミングで右辺の計算結果のオブジェクトへの参照がnodeに入る。headはListNodeのオブジェクトだが、head.valは具体的な数値、head.nextは他のlistnodeへの参照。元のリストの先頭への参照は慣習的に残しているっぽい。 | ||
|
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. head.valもintのオブジェクトですよ。変数は全てオブジェクトへの参照です。
Owner
Author
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. ありがとうございます、認識を改めます |
||
|
|
||
| - listでもsetでもいいのか? | ||
|
|
||
| →重複した値が来ると考えた場合にlistのほうが良い? | ||
|
|
||
| →AI回答「setに入れているのはnode(オブジェクト自体)であってnode.valではありません。例えばval=2のノードが2つあっても、それぞれ別のオブジェクトなのでid()が異なり、setでは別物として扱われます。」 | ||
|
|
||
| →>>(そういえばsetって重複が許されないからテストケースによっては上手くいかなそう) | ||
|
|
||
| →nodeに入っているのはオブジェクト自体なので上手くいく。if node in visitedで見ているのはオブジェクトのidが合致しているかどうか。なので同じ値が入ってきてもオブジェクトidが違うので上手くいく。はず。 | ||
|
|
||
| →前回深堀できなかった個所も深堀できて理解が深まった。やっぱりオブジェクトのところでもう一度読んでおく。 | ||
|
|
||
| https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.wrv8idqm5j2b | ||
|
|
||
| - 計算量とかの話は全く理解できていないのでこの機会に理解しておく | ||
|
|
||
| →https://qiita.com/take-yoda/items/661d5a2b6fc2e5155309 | ||
|
|
||
| データ量nが増えた時にどれだけ処理時間が増えるか。 | ||
|
|
||
| https://amdlaboratory.com/amdblog/python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8big-o-notationbig-o-%E8%A8%98%E6%B3%95/ | ||
|
|
||
|
|
||
|
|
||
| # step3 | ||
|
|
||
| ```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]: | ||
| print(id(head)) | ||
| node = head | ||
| print(id(node)) | ||
| visited = set() | ||
| while node is not None: | ||
| if node in visited: | ||
| return node | ||
| print(id(node)) | ||
| # setはadd listはappend | ||
| visited.add(node) | ||
| node = node.next | ||
| # print(id(visited)) | ||
| ``` | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| node = head | ||
| visited = set() | ||
| while node: | ||
| if node in visited: | ||
| return node | ||
| visited.add(node) | ||
| node = node.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.
list に特定の値が含まれているかを確認するとき、すべての要素を一つ一つ調べなければなりません。これには時間がかかります。時間計算量は O(n) となります。
set を使用すると、特定の値が含まれているかを確認するとき、高速に調べることができます。時間計算量は O(1) となります。
配列・ハッシュテーブルあたりのデータ構造について調べ、余裕があれば CPython の 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.
ありがとうございます、時間計算量の理解もあいまいだったので調べなおしました。
配列ハッシュテーブルあたりもイメージは湧きましたが衝突の回避方法のあたりが腑に落ちてないので読み直してみます
https://qiita.com/alswnd/items/428014509e52297b3a1b