diff --git a/142. Linked List Cycle II.md b/142. Linked List Cycle II.md new file mode 100644 index 0000000..f55f46f --- /dev/null +++ b/142. Linked List Cycle II.md @@ -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 (Solution.py) +``` + +returnでprintを返すのかな? +→問題文読んだらサイクルの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への参照。元のリストの先頭への参照は慣習的に残しているっぽい。 + +- 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 +```