Skip to content

142. Linked List Cycle II #3

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 8 commits into
base: main
Choose a base branch
from
Open

142. Linked List Cycle II #3

wants to merge 8 commits into from

Conversation

pineappleYogurt
Copy link
Owner

@pineappleYogurt pineappleYogurt commented Dec 9, 2024

前回からかなり間空いてしまったのですが再開しました、レビューしていただければ幸いです。

解いた問題

Linked List Cycle II - LeetCode - https://leetcode.com/problems/linked-list-cycle-ii/description/

次に解く問題

83. Remove Duplicates from Sorted List

- こちらで解いてみると問題の意図に気付いた
- hashMapは常にループの最初を検知できるが、two-pointerの場合ループ途中のノードで検知する可能性がある。
- 5分経っても解法がわからないのでaraiさんの解説動画を見る
- フロイドの循環検出法というらしい
Copy link

Choose a reason for hiding this comment

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

フロイドの循環検出法はソフトウェアエンジニアの常識には含まれていないと思います。ただ、 LeetCode でコーディングやアルゴリズムの勉強をしている人は、なぜか知っているような気がします。

fast = fast.next
slow = slow.next
return fast
```
Copy link

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/1221030192609493053/1225674901445283860

Copy link
Owner Author

Choose a reason for hiding this comment

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

他の方のコードを読むこと失念していました。
次の問題からはstep2のタイミングで自分なりのリファクタリングの後に他の方の解答例を読んでみようと思います。

- フロイドの循環検出法というらしい
- https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%AD%E3%82%A4%E3%83%89%E3%81%AE%E5%BE%AA%E7%92%B0%E6%A4%9C%E5%87%BA%E6%B3%95
- araiさんの解説で理論はわかったがどこまでの理解が必要なのか
- このような問題がそのまま出るのか他のアルゴリズムを組み居合わせるような応用が出るのか
Copy link

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/1246383603122966570/1252209488815984710

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます、自分の理解と同じことを確認できました!

- 問題文の文意(前回の141からとの違い、何を問うているのか)があまり読み取れなかった
- 前回の問題との違いはBoolで返していた値をNodeにするくらいかなと考えたが、流石にそんな簡単なことあるのかと思った
- とりあえず時間制限もあるので、Nodeを返すよう修正してみたところ通った
- hashMapとtwo-pointerのどちらで解こうか考えたがシンプルなhashMapを選んだ
Copy link

Choose a reason for hiding this comment

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

私の感じる出題意図はこういうものです。

本当にできない人もいるので、できたら簡単な問題にしたい。すぐに解ける人もいるのでそうだとしたら議論をすることによって、色々な能力を推し量りたい。本当に知りたいことは、仕事ができるかで、つまりは「コードの仕様を変えたいときに巨大なコードベースを掘って見つけ、該当箇所を変更する綺麗な案を作り、他のチームメイトにそれでうまくいくことを説明して、プロダクションに持っていくこと」なので、コードが書けるかどうかはあまり重要ではない。

最近だと、プログラミングコンテストの影響で、自分が書いたコードすら読めない人が多い。

そこで、「簡単な問題を出して見るが、一捻りしたアハ解答があるので、議論をしてみて、ヒントを出しながらフロイドの方法に到達すると、コミュニケーションが取れてコードが読めるかなどが確認できて良い」という思考で出ていると思われます。

https://docs.google.com/presentation/d/1Ny4kmHE2FZMI0AuPxImokweGoAE73RAGivjDJg0kG80/edit#slide=id.g22c5f8cce92_0_0

Copy link
Owner Author

@pineappleYogurt pineappleYogurt Dec 10, 2024

Choose a reason for hiding this comment

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

つまりは最終的に、『多少のヒントをもらいながら自力でアハ解答を導き出せる状態』ようになる必要があるのでしょうか?
仮にそうだとした場合、今の自分の解き方でarai60を解き切った時にその状態になれるのか、もしかするとやり方を変えるべきなのではと考えています。

今の自分は、ルールとして提示されていた

新井さんの問題順番にやっていきます。一日一問で最初はいいでしょう。答えを見ずに考えて、5分考えて分からなかったら答えを見てください。答えを見て理解したと思ったら、答えを隠して書いてください。筆が進まず5分迷ったら答えを見てください。そして、見ちゃったら一回全部消してやり直しです。答えを送信して、正解になったら、まずは一段階目です。次にコードを読みやすくするようにできるだけ整えましょう。これで動くコードになったら二段階目です。そしたららまた全部消しましょう。今度は、時間を測りながら、もう一回、書きましょう。書いてアクセプトされたら文字消してもう一回書きましょう。これを10分以内に一回もエラーを出さずに書ける状態になるまで続けてください。3回続けてそれができたらその問題はひとまず丸です。

を元に以下のように解いています。

**step1**
1. 解いてみて5分考えてわからなければ答えをみる。
2. 理解できたら隠してもう一度解く、5分迷ったら答えを見る。
3. 5分で回答が書けるようになったら第1段階クリア

**step2**
1. コードをできるだけ整える
2. 整えて動くようになったら第2段階クリア

**step3**
1. 10分以内に一回もエラーが出ないようにする
2. 3回続けてできるようになればクリア

これを繰り返すごとでarai60で紹介されている解法に関しては覚えることはできるものの、odaさんが書かれているアハ解答というのができるようになるのかという不安があります。

アハ解答を思いつけるようになるには、1により時間をかけて自分で解答を思いつく必要があるのかなと考えましたが、今のやり方を続けていくことでアハ解答的な発想が身についていくのでしょうか?
それともそもそもこの視点がずれているのでしょうか?

Copy link

Choose a reason for hiding this comment

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

いや、私の意図としては、パズルが解けるかみたいなのはほとんど評価の対象になっていないです。

ただ、同じ問題を出しても5分で解く人と1時間かかっても解けない人がいるので、5分で解かれてしまった場合、出題者は時間が余って困ります。

そこで、時間をつなぎながら「コードの仕様を変えたいときに巨大なコードベースを掘って見つけ、該当箇所を変更する綺麗な案を作り、他のチームメイトにそれでうまくいくことを説明して、プロダクションに持っていくこと」ができるかを確認しに行きます。

そうすると、パズル的な他の解き方がある問題というのはとてもいいです。なぜかというと「パズル的な解き方を出題者が説明して、それを理解して実装してもらう」と、上の要素のうち「自然言語での説明を理解する」「変更案を作る」「コードの説明する」といった要素が自然に確認できるし、候補者がいい体験だったと思ってくれるからです。

面接官やハイアリングマネージャーの気持ちを考えてみましょう。

Copy link
Owner Author

Choose a reason for hiding this comment

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

確かにその意図で言うと、提示されているleetcodeのルールで解いていけば議論する力は養われていきそうです!
ありがとうございます、納得した上で進めていきそうです!

@oda
Copy link

oda commented Dec 10, 2024

ああ、あと、PR のタイトルに問題名をいれておくと、後で Discord 内で検索ができるようになるのでお願いしたいです。

@pineappleYogurt pineappleYogurt changed the title 142 142. Linked List Cycle II Dec 10, 2024
Comment on lines +97 to +99
while fast is not slow:
fast = fast.next
slow = slow.next
Copy link

Choose a reason for hiding this comment

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

この部分のfastについては、「サイクル中にあるノード」とか、「ぶつかった地点から1ずつ進めるノード」みたいな意味で、fastではなくなっているので、別の変数を用意してもいいと思います。

Copy link
Owner Author

@pineappleYogurt pineappleYogurt Dec 11, 2024

Choose a reason for hiding this comment

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

確かに元の意味でのfast,slowとは違っていますが、
自分はこのアルゴリズムを
https://github.com/pineappleYogurt/leetCode/pull/3/files#r1878280764
の様に理解していて、ここで用いられるfast, slowがこれ以前のfast, slowと同じものであるという意味を明示するために、そのままfast, slowを用いていいかなと思いました。

while fast is not slow:
fast = fast.next
slow = slow.next
return fast

Choose a reason for hiding this comment

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

t0hsumiさんと同様で、ポインタの再配置の後はslow, fastの差異はその役割のみで速度的な違いはないので別の変数を作ってコピーしてやるといいと思います。
odaさんが触れていた自然言語での説明というのもこちらの方がコードの中身との合致部分が増えて少し納得してもらいやすくなるのでは

Copy link
Owner Author

Choose a reason for hiding this comment

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

https://github.com/pineappleYogurt/leetCode/pull/3/files#r1880502989
と同じなのですが、速度的な意味は無くなるもののそれまで使っていたfast, slowと同じものを指すという意図で使っていました。

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.

5 participants