Conversation
|
|
||
| class Solution: | ||
| def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
| if head is None or head.next is None: |
There was a problem hiding this comment.
以下のループの箇所でhead.next is Noneの場合ループを抜けるので上記のif文のhead.next is Noneは不要と理解しました。
そういう意味だとhead is Noneも以下の処理に含まれているので不要な気もしてきました。。
while head:| - XXX | ||
| - | ||
| - Linked Listとは? | ||
| - ノードの値と次の要素の参照を持っているデータの構造体。配列と比較してデータの挿入と削除が可能。 |
There was a problem hiding this comment.
「配列と比較してデータの挿入と削除が可能。」の部分がよくわからなかったのですが、固定長配列の話をしていますか?確かに固定長配列の場合、サイズを変えようとしたら新たにメモリを確保してそこに要素をコピーする必要があると思うのですが、そういう意味でデータの挿入と削除ができないということでしょうか?
他にも配列とはそもそも何なのか、動的配列、Pythonのリストの内部の仕組み、配列/連結リストの末尾や真ん中への要素の追加・削除の時間計算量などを調べてみるといいと思います
There was a problem hiding this comment.
浅い知識で深掘りできてなかったので、あまり深い意味はなくメモ書きしてしまってました。。
もう少し記載いただいた内容のあたりを調べてみようと思います!
| while head: | ||
| if head.val == "*": | ||
| return True | ||
| head.val = "*" |
There was a problem hiding this comment.
入力を破壊して求めるやり方もできますし、入力を破壊しないで求めるやり方もできそうですよね。
There was a problem hiding this comment.
"" に特別な意味をつける方法は、""を別の人が別の特別な意味をつけると破綻しますので、デメリットが大きいのでそのデメリットに見合うものでなかったら避けましょう。また、None などのほうが特別の意味をもたせることのデメリットが小さめです。あと、入力を破壊していいかは状況次第ですのでそれも別途考えましょう。
There was a problem hiding this comment.
ありがとうございます。確かに自分ルールで特別な意味を持たせると、他の人が別の意味を持たせてしまうと破綻するので非推奨に思えますね、、Noneなどの予約語で特別な意味を持たせることはまたメリットデメリットの度合いが異なりそうですね。。新しい観点で勉強になりますm(_ _)m
また、入力を破壊するというところはもう少し意識して実装したいと思います。
入力を破壊した実装をすると以下のようなことが起きてしまうので引き数を破壊せず実装する方がより良いのではないかと個人的には思いました!
- 引き数が想定外の値に変わってしまうのでその引き数を利用する際に想定外の挙動が起きる
- 特別な意味を持たせた値があったとして、その値をたまたまもともとList内に持っていた場合に破綻する
| fast = fast.next.next | ||
| if slow == fast: | ||
| return True | ||
| return False |
There was a problem hiding this comment.
汎用的な方法として使えそうという意味合いで、1st_step.py のようなやり方いいですね。
There was a problem hiding this comment.
ありがとうございます。若干力業感は否めないですが・・かつstep2以降は知ってる人が解けるアルゴリズムのようなのでよりそのように感じるのかも知れないですね。。
今後、汎用的に利用できるかという視点を持って実装したいと思います!
| if head.val == "*": | ||
| return True | ||
| head.val = "*" | ||
| head = head.next |
There was a problem hiding this comment.
head は通常連結リストの先頭のノードを表すそうなので、別の変数名にした方が良いかもしれません。
h1rosaka/arai60#2 (comment)
There was a problem hiding this comment.
ありがとうございます。agreeです。headを動かすとheadじゃないやん!ってなりますもんね。。
こういった場合は別の変数名にしようと思います!
| def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
| if head is None or head.next is None: | ||
| return False | ||
| while head: |
There was a problem hiding this comment.
while head is not None の方がPEP8的にはおすすめのようでした。
None のようなシングルトンと比較をする場合は、常に is か is not を使うべきです。絶対に等値演算子を使わないでください。また、 本当は if x is not None と書いているつもりで、 if x と書いている場合は注意してください - たとえば、デフォルトの値がNoneになる変数や引数に、何かしら別の値が設定されているかどうかをテストする場合です。この「別の値」は、ブール型のコンテクストでは False と評価される(コンテナのような)型かもしれませんよ!
There was a problem hiding this comment.
なるほど、、今の書き方で問題ないですが、型によっては問題が起きうることがあるということですね。。
if x is not Noneは対Noneのみだけで判別できているが、if xだとNone以外も含めFalseになり得るということですね。
対Noneを判別したい場合は確かに前者の方が安全な気がしますね。使い方を注意したいと思います。
| fast = fast.next.next | ||
| if slow == fast: | ||
| return True | ||
| return False |
There was a problem hiding this comment.
ちなみにこの解き方はフロイドのアルゴリズムと呼ばれる手品みたいなものだそうです。
setを使った解き方もありますので、ご参考まで
There was a problem hiding this comment.
手品という表現は面白いですね・・・知る人ぞ知るトリックって感じのアルゴリズムってことですね。
必ずしも知ってなくてもよいようなアルゴリズムなのですね。。
setを使った解き方もできるのですね!確認してみます。
There was a problem hiding this comment.
私の科学手品という表現の意図は、科学に興味を引かせるために使うもの、くらいのつもりです。
たとえば、こういうやつです。偏光で黒い板があるように見えるというもの。
https://www.sci-museum.jp/study/staff/94/
|
valを書き換えていく方法は思いつかなかったので勉強になりました。 |
問題: 141. Linked List Cycle
https://leetcode.com/problems/linked-list-cycle/description/
言語: Python