-
Notifications
You must be signed in to change notification settings - Fork 0
0141. linked list cycle #1
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
base: main
Are you sure you want to change the base?
Changes from all commits
b4a94f9
b321ca9
2aedd3b
45bd91a
7b254fa
265014a
f18ad2d
bcbdcfb
6be1af3
043a0af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なるほど、、今の書き方で問題ないですが、型によっては問題が起きうることがあるということですね。。 |
||
if head.val == "*": | ||
return True | ||
head.val = "*" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 入力を破壊して求めるやり方もできますし、入力を破壊しないで求めるやり方もできそうですよね。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "" に特別な意味をつける方法は、""を別の人が別の特別な意味をつけると破綻しますので、デメリットが大きいのでそのデメリットに見合うものでなかったら避けましょう。また、None などのほうが特別の意味をもたせることのデメリットが小さめです。あと、入力を破壊していいかは状況次第ですのでそれも別途考えましょう。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。確かに自分ルールで特別な意味を持たせると、他の人が別の意味を持たせてしまうと破綻するので非推奨に思えますね、、Noneなどの予約語で特別な意味を持たせることはまたメリットデメリットの度合いが異なりそうですね。。新しい観点で勉強になりますm(_ _)m また、入力を破壊するというところはもう少し意識して実装したいと思います。
|
||
head = head.next | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. head は通常連結リストの先頭のノードを表すそうなので、別の変数名にした方が良いかもしれません。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。agreeです。headを動かすとheadじゃないやん!ってなりますもんね。。 |
||
return False |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
if head is None or head.next is None: | ||
return False | ||
slow = fast = head | ||
while fast and fast.next: | ||
slow = slow.next | ||
fast = fast.next.next | ||
if slow == fast: | ||
return True | ||
return False | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ちなみにこの解き方はフロイドのアルゴリズムと呼ばれる手品みたいなものだそうです。 setを使った解き方もありますので、ご参考まで There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 手品という表現は面白いですね・・・知る人ぞ知るトリックって感じのアルゴリズムってことですね。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 私の科学手品という表現の意図は、科学に興味を引かせるために使うもの、くらいのつもりです。 たとえば、こういうやつです。偏光で黒い板があるように見えるというもの。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
slow = fast = head | ||
while fast and fast.next: | ||
slow = slow.next | ||
fast = fast.next.next | ||
if slow == fast: | ||
return True | ||
return False | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 汎用的な方法として使えそうという意味合いで、1st_step.py のようなやり方いいですね。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。若干力業感は否めないですが・・かつstep2以降は知ってる人が解けるアルゴリズムのようなのでよりそのように感じるのかも知れないですね。。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,107 @@ | ||
# 問題文 | ||
# 問題概要 | ||
問題: 141. Linked List Cycle | ||
|
||
https://leetcode.com/problems/linked-list-cycle/description/ | ||
|
||
言語: Python | ||
|
||
# Step1 | ||
|
||
かかった時間:XXmin | ||
かかった時間:10min | ||
|
||
思考ログ: | ||
- 問題を理解する。 | ||
- AAA | ||
- BBB | ||
- XXX | ||
- YYY | ||
|
||
```python | ||
- Linked Listが与えられて、サイクル(循環)が存在するかを判定する問題。 | ||
|
||
- どのような解き方ができそうか。 | ||
- Linked Listをループさせて、要素に印をつけていき、印のある要素が再度出現した場合はTrueを、ループを抜けてしまった場合はFalseを返す方法でいけそう。 | ||
|
||
```python | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
if head is None or head.next is None: | ||
return False | ||
while head: | ||
if head.val == "*": | ||
return True | ||
head.val = "*" | ||
head = head.next | ||
return False | ||
|
||
``` | ||
疑問点: | ||
- XXX | ||
- | ||
- Linked Listとは? | ||
- ノードの値と次の要素の参照を持っているデータの構造体。配列と比較してデータの挿入と削除が可能。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 「配列と比較してデータの挿入と削除が可能。」の部分がよくわからなかったのですが、固定長配列の話をしていますか?確かに固定長配列の場合、サイズを変えようとしたら新たにメモリを確保してそこに要素をコピーする必要があると思うのですが、そういう意味でデータの挿入と削除ができないということでしょうか? 他にも配列とはそもそも何なのか、動的配列、Pythonのリストの内部の仕組み、配列/連結リストの末尾や真ん中への要素の追加・削除の時間計算量などを調べてみるといいと思います There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 浅い知識で深掘りできてなかったので、あまり深い意味はなくメモ書きしてしまってました。。 |
||
- 'pos'とは? | ||
- 循環の始まりのindexを表す。-1の場合、循環しない扱いとなる。 | ||
- 引数のLinked Listが書き換わってしまうので、変更せず解く方法はないか。 | ||
|
||
参考リンク | ||
- | ||
- Linked List | ||
- https://www.geeksforgeeks.org/linked-list-data-structure/ | ||
|
||
# Step2 | ||
かかった時間:XXmin | ||
かかった時間:15min | ||
|
||
思考ログ | ||
- XXX | ||
|
||
```python | ||
|
||
``` | ||
- その他の解き方が無いか調べてみる。 | ||
- フロイドの循環検出法というもので対応できそう | ||
- 速く動く、遅く動く2つのインデックスを利用して循環を検出するアルゴリズム | ||
- 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 | ||
|
||
- XXX | ||
```python | ||
|
||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
if head is None or head.next is None: | ||
return False | ||
slow = fast = head | ||
while fast and fast.next: | ||
slow = slow.next | ||
fast = fast.next.next | ||
if slow == fast: | ||
return True | ||
return False | ||
``` | ||
|
||
# Step3 | ||
かかった時間: XXmin | ||
かかった時間: 5min | ||
|
||
上記を書き直し、実装。 | ||
上記を書き直して実装。 | ||
|
||
```python | ||
- 1行目のif文はwhile文の条件と重複しているため破棄。 | ||
|
||
```python | ||
# Definition for singly-linked list. | ||
# class ListNode: | ||
# def __init__(self, x): | ||
# self.val = x | ||
# self.next = None | ||
|
||
class Solution: | ||
def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
slow = fast = head | ||
while fast and fast.next: | ||
slow = slow.next | ||
fast = fast.next.next | ||
if slow == fast: | ||
return True | ||
return False | ||
``` | ||
|
||
# Step 4 | ||
- レビューを持って修正を行う | ||
# Step4 | ||
- レビューを受けて修正を行う | ||
|
||
```python | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
head.next is None
はなくても大丈夫だと思いますThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
以下のループの箇所で
head.next is None
の場合ループを抜けるので上記のif文のhead.next is None
は不要と理解しました。そういう意味だと
head is None
も以下の処理に含まれているので不要な気もしてきました。。