Skip to content

Linked List Cycle 1 #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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions linkedListCycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# LinkedListCycle1

## step1

所要時間 30分

10分ほど考えてわからなかったので解説動画を見た。
Linked Listを知らなかったので調べた。
[Linked Listとは](https://astrostory.hatenablog.com/entry/2020/02/24/070213)
[Linked ListとArray Listの違い](https://qiita.com/BumpeiShimada/items/522798a380dc26c50a50)
その後動画を参考にコードを書いた。

```python
class Solution:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このアルゴリズムは、フロイドの循環検出法と呼ばれているアルゴリズムで、ソフトウェアエンジニアの常識には含まれていないと思います。想定解法は、辿ったノードを set 等に入れておき、過去に辿ったノードにたどり着いたら return True するというものだと思います。そちらの解法でも書いてみていただけますか?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

わかりました。そちらの解法でも行ってみようと思います。

def hasCycle(self, head: Optional[ListNode]) -> bool:
if not head:
return False
slow = head
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slow = fast = headとも確か書けましたね。それについての議論がdiscordにあった気がするので調べてみると良いかもです

fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if fast == slow:
return True
break
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

step2 で既に消されていますが、 return True で関数から抜けるため、直後の break は余分だと思います。

else:
return False

```

## step2

所要時間30分

step1を修正する
returnを行うと関数自体が終了することを理解していなかったため必要のないbreakとelseを入れてしまった。

```python
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
if not head:
Copy link

@h1rosaka h1rosaka Sep 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pep8のこちらの記載を考慮すると、if head is None:の方がおすすめです。

None のようなシングルトンと比較をする場合は、常に is か is not を使うべきです。絶対に等値演算子を使わないでください。また、 本当は if x is not None と書いているつもりで、 if x と書いている場合は注意してください - たとえば、デフォルトの値がNoneになる変数や引数に、何かしら別の値が設定されているかどうかをテストする場合です。この「別の値」は、ブール型のコンテクストでは False と評価される(コンテナのような)型かもしれませんよ!

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参照してみます。ご教授いただきありがとうございます。

return False
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if fast == slow:
return True
#break 削除
#else: 削除
return False

```

<https://qiita.com/toshi_machine/items/3b2a5c04da949ac78298>
上のリンクで紹介されているコードがなぜうまくいくのかわからないので考えてみた。

```python
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head:
return False
slow = head
fast = head.next
#なぜfast = head.nextとしても通るのだろうか
#0番目のリンクリストが存在するとして考えれば良い。またここをfast = head.nextとしないと次の slow != fastに引っかかる 

while slow != fast:
if not fast or not fast.next:
return False
slow = slow.next
fast = fast.next.next
return True
```

0番目のリストを想定するのは無意味な仮定に思えるのでここでは採用しない。
"slowとfastが同じでない時、動かし続ける"と"fastとfast.nextが存在する時、動かし続ける"ではコードの意味が変わる気がする。
前者はループを見つけることに重きをおいていて後者はループがないものを見つけることに重きをおいていると言えるのではないか?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すいません、ここに書かれていることをちゃんと理解したわけではないので、見当違いなことを言ってるかもしれないですが、ここでやっているフロイドの循環検出法は単純に、足の遅いAさんと足の速いBさんがいたとき、循環しているのであれば、いずれBさんはAさんに追いつくはずという理屈なので、難しく考えすぎている気もしました

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど、確かに難しく考えすぎていたかもしれません。
循環しているなら追いつくという理屈ならスタート地点はどこにしても結果は変わらないですね。
ありがとうございます。


## step3

所要時間5分

何も見ないで三回連続で成功するまでコードを書いた
一度`while fast or fast.next`としてしまった。コードの意味をきちんと理解していないから起こすミスであると考える。

最終的なコードはstep2と同様であるため示さない。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、ちなみにこれ残しておいてもいいと思います。だんだんどう理解したのかが最後に現れるようになってきますから。

Empty file removed test.txt
Empty file.