Skip to content

141. Linked List Cycle#2

Open
canisterism wants to merge 4 commits intomainfrom
141_linked_list_cycle
Open

141. Linked List Cycle#2
canisterism wants to merge 4 commits intomainfrom
141_linked_list_cycle

Conversation

@canisterism
Copy link
Copy Markdown
Owner

@canisterism canisterism marked this pull request as ready for review July 21, 2024 06:29
@canisterism canisterism force-pushed the 141_linked_list_cycle branch from e860962 to f5b72da Compare July 21, 2024 07:01
Copy link
Copy Markdown

@hayashi-ay hayashi-ay left a comment

Choose a reason for hiding this comment

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

良いと思います。

- セルフツッコミしてみる
- もうちょっと最初の5行ぐらいをシュッと書けるかも
- 先にhead.valをaddするんじゃなくて、そのまま全部whileの中に入れられないかな
- `has_visited = visited_nodes.add?(current.val).nil?`が読みづらい気がする
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

includeメソッド使う方が素直な気がします。
https://docs.ruby-lang.org/ja/latest/class/Set.html#I_--3D--3D--3D

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

確かに!ドキュメント途中までしか見てませんでした 😇

return false if head.nil? || head.next.nil?

visited_nodes = Set.new
visited_nodes.add(head.val)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

私もStep3のコードのように、headを特別扱いしないバージョンの方が好みです。

@hroc135
Copy link
Copy Markdown

hroc135 commented Jul 21, 2024

currentという命名についていろいろ議論されているので
hroc135/leetcode#3 (comment)
など参考にしてみてください。

- Step1はwhileの条件が読みにくいかも?改善ポイントってこういうのでいいのかな?
- わからなかったので他の人のPRを探す
- https://github.com/sendahuang14/leetcode/pull/1/files
- HashMapでたどったノードをメモする解法。チラッと考えたけど前に見たことある解法で解くイメージが先行して試してなかった。
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

講師陣の方によると、setを使った解法の方がオーソドックスというか想定解だと思われますね。
tk-hirom/Arai60#1 (comment)

- そういえば計算量について全然意識できてなかったことに気づく
- 今のアルゴリズムだとどうなるんだ...?
- 時間計算量は最大でO(N)?
- 空間計算量はO(1)でいいのかな
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

合っていると思います。計算量を見ると、空間計算量がフロイドの解法の方がO(1)で良いですね。setを使うと最悪計算量がO(N)になるかと思います。(すべてのノードの値をsetに入れることになるため。)

@Mike0121
Copy link
Copy Markdown

コード自体は問題ないかと思いました。
メモにいくつかコメントをしてみました。

fast = fast.next.next
end
end
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

このコードで一番謎なのは、nil チェックするのと動かすのが対になっていないところでどう考えているのかが知りたいです。動かす前に確認したいし、確認したら動かしたい気持ちになりませんか。

Copy link
Copy Markdown

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/1192728121644945439/1194203372115464272

動かせるか確認してから、動かさない
ニンジンを切って、炊飯器のスイッチをいれて、ジャガイモを切れ、みたいな指示書かないじゃないですか。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

言われてみれば確かにそうですね。
これを書いた時の気持ちとして、「まず循環してるかの結果が出てたらすぐに判定してループを抜けたい」が先に来てif節を書いてました。

2歩動かせるか確認して動かせなかったらループはない。動かせるなら動かす。同じところにきたらループがあったと宣言

解いてる時にこの順番の発想が浮かびませんでした!ちょっと書き直してみます 👀

return false if head.nil? || head.val.nil?
slow, fast = head, head

while !fast.nil? && !fast.next.nil? # <- fastがnilで落ちる
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これ、loop do + if return に分解してみて欲しいです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

やってみました!仰ってることが肌で分かった気がします。
フロイドの循環検出法をloop+ifで書く

current = head.next

while !current.nil? do
has_visited = visited_nodes.add?(current.val).nil?
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これ、val が unique であるという保証あるんでしたっけ? Set は Object 入れられたと思いますので、そちらのほうが素直では。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

確認したのですが、勝手にvalがuniqueだと思い込んでました😇
(leetcode上のサンプルのテストケースは通ってたけどsubmitしたら他のケースで通ってませんでした)

Setにはプリミティブなintとかstringぐらいしか入らないと思い込んでたんですがHashも入るんですね。
ありがとうございます!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

https://docs.ruby-lang.org/ja/latest/library/set.html

Set は内部記憶として Hash を使うため、集合要素の等価性は Object#eql?Object#hash を用いて判断されます。したがって、集合の各要素には、これらのメソッドが適切に定義されている必要があります。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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


while !current.nil? do
has_visited = visited_nodes.add?(current.val).nil?
has_visited = visited_nodes.add?(current).nil?
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

既存のを修正するより新しいSTEPで追加してもらうほうがレビューしやすいかなと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

あああすみません、Step4で追記しました

end
```
- 以下Odaさんのレビューを受けた時のログ
- valはすべてのノードでuniqueでないので、Hash自体を詰めないと同じvalが出てくると正しい結果にならない。↓
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

HashというよりObject(ListNode)を詰めるですかね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants