Create 0142-linked-list-cycle-ii.md#2
Conversation
| > * まず **slow**(1歩ずつ)と **fast**(2歩ずつ)を動かすと、ループがある場合いつか同じ場所で会う。 | ||
| > * その後、**一方を head に戻して、両方を 1 歩ずつ進める**と、次に会う場所がループの入口になる。 | ||
|
|
||
| おそらく、リストの長さとサイクルの長さを文字で置いて証明できる気がする。 |
There was a problem hiding this comment.
数式での証明も可能ですが、Floydのアルゴリズムは自然言語でも直観的に説明できます。
https://discord.com/channels/1084280443945353267/1246383603122966570/1252209488815984710
しかし、実際の面接におけるFloydのアルゴリズムの出題意図はおおむね次のようなものらしいので、以上の説明を自分で思いつけなくても特に問題はないと思います。
pineappleYogurt/leetCode#3 (comment)
There was a problem hiding this comment.
補足ありがとうございます!
しかし、実際の面接におけるFloydのアルゴリズムの出題意図はおおむね次のようなものらしいので、以上の説明を自分で思いつけなくても特に問題はないと思います。
pineappleYogurt/leetCode#3 (comment)
なるほどですね。常識を問う手段ではあるが、それ自体常識ではないってことですね。
数式での証明も可能ですが、Floydのアルゴリズムは自然言語でも直観的に説明できます。
https://discord.com/channels/1084280443945353267/1246383603122966570/1252209488815984710
「かめがスタート地点に戻った時、うさぎはどこにいるでしょうか。実は、うさぎは衝突点にいます。なぜかというと、うさぎは倍速で走っているからです。スタート地点から衝突点を通って衝突点に到達するうさぎルートの長さは、スタートから衝突点に到達するかめルートの2倍だからです。」
の部分が前文から飛躍しているように感じられました。
少し調べ、「亀が歩いた距離がサイクル長の整数倍なので、」という行間を埋めることで理解に達しました。
パズルとして面白かったです。
There was a problem hiding this comment.
ありがとうございます。
いやたしかに、その衝突点で衝突した(=両者の歩いた距離にサイクル長の整数倍の差が生じた)という事実から簡単に導けますね。
かめがスタート地点に戻った時、うさぎはどこにいるでしょうか。実は、うさぎは衝突点にいます。なぜかというと、うさぎは倍速で走っているからです。スタート地点から衝突点を通って衝突点に到達するうさぎルートの長さは、スタートから衝突点に到達するかめルートの2倍だからです。
ここはそういう意味ですね。
|
どの方法も読みやすいコードでした。Floydのアルゴリズムに関して若干補足を入れています。 |
|
思考過程もコードも分かりやすくて良いと思います! |
ありがとうございます! 同意します。 この程度の処理なので、おっしゃるとおりで関数化はためらわれました。 |
| no cycleでNoneを返すところ、冗長だと思ったので、 | ||
| ```python3 | ||
| if not has_cycle: | ||
| return |
There was a problem hiding this comment.
ここは明示的にNoneを返す方が分かりやすいかなと思いました。
returnとだけ書く場合は返り値を一切気にしない関数の場合に使うのが良いように思います。
nanae772/leetcode-arai60#3 (comment)
There was a problem hiding this comment.
ありがとうございます。
ですね、同意します。
| fast = head | ||
| slow = head | ||
| has_cycle = False | ||
| while fast is not None and fast.next is not None: | ||
| fast = fast.next.next | ||
| slow = slow.next | ||
| if fast is slow: | ||
| has_cycle = True | ||
| break |
There was a problem hiding this comment.
私が過去にいただいたコメントですが、こちらを一つの関数として切り出すと見通しがよくなるかなと思います。
理由に関しては以下のリンクをご参照ください。
nanae772/leetcode-arai60#3 (comment)
またフラグによる分岐はgotoよりも構造化されていないという意見もあったので、それも関数化することによって避けることができるかなと思います。
There was a problem hiding this comment.
ありがとうございます。
確かに、 前半は関数として切り出すことで、前半の変数をもう使わない/操作しないと明示できるのはいいですね。
フラグとgotoも見てみます。
| if fast is slow: | ||
| has_cycle = True | ||
| break | ||
| if not has_cycle: |
There was a problem hiding this comment.
コードの整え方のところを見ておいてください。要はよく使う変形があるんですよ。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.9kpbwslvv3yv
この問題:https://leetcode.com/problems/linked-list-cycle-ii/
次に解く問題:https://leetcode.com/problems/remove-duplicates-from-sorted-list/