Skip to content

Create ReverseLinkedCycle.md #8

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

Conversation

SanakoMeine
Copy link
Owner


return sentinel.next
```
- 他の人の回答をみてると全部のnextの情報を繋ぐのをやめてメモリを節約するとMemoryLimitに収まるらしいので書いてみる
。printしてみるとリストの各要素がnextの果てまで記録していて、空間計算量がO(N^2)になっていた様で、全く気づいてなかった。
Copy link

Choose a reason for hiding this comment

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

これは、二重に間違えています。試しに、

        reversed.next = None
        return sentinel.next

というふうに、return の上に一行足してみましょう。これで動くはずです。

そのうえで、もう一回考察してみて下さい。

Copy link
Owner Author

Choose a reason for hiding this comment

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

試してみたら動きました。なるほど...。

print(reversed.next)してみたところ"Error - Found cycle in the ListNode"が表示されました。while文の中でずっとループを作りながら遡っていたから、そこにトラップされてエラーを吐いていたのですね。

「2重」と仰っていたのはこれに加えて、意図した動きをしていたら空間計算量は普通にO(N)だからですね。
printされて出てくる

ListNode{val: 5, next: ListNode{val: 4, next: ListNode{val: 3, next: ListNode{val: 2, next: ListNode{val: 1, next: None}}}}}

も今見るとリストの大きさ分保存されているだけですね(今見るとむしろ何を見てO(N^2)と思ったのか不思議です...。Memory Limit Exceededという語感から空間計算量に問題があるという先入観を持ってしまったのだと思います。)。

Copy link

Choose a reason for hiding this comment

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

理解を一応確認します。最後に pop してきたものの next がその一つ前のやつになっているので、最後の2要素がループになっています。

Memory Limit Exceeded になるのは、おそらく出力を検証している部分が出力をリストに直してから結果を検証しています。そして、そこが無限ループに陥っています。

ここで得られる教訓は、仕事を引き継ぐときに何を引き継いでいるかを意識しようということ、です。

Copy link
Owner Author

@SanakoMeine SanakoMeine Jan 8, 2025

Choose a reason for hiding this comment

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

最後に pop してきたものの next がその一つ前のやつになっているので、最後の2要素がループになっています

これは理解できておりました。

出力を検証している部分が出力をリストに直してから結果を検証しています。

具体的な検証の仕方のイメージはついておらず、この推測は立っておりませんでした。

ここで得られる教訓は、仕事を引き継ぐときに何を引き継いでいるかを意識しようということ、です。

ノード1つ分を処理し終えた時にどこまで仕事が終わっているか認識が甘かったために、最後の要素が1つ前の要素を指したままでループを形成してしまったことに気づけなかったものと認識しています。その意味でおっしゃる教訓はキャッチできていると考えています。

scan = scan.next

sentinel = ListNode(0, scan)
reversed = sentinel
Copy link

Choose a reason for hiding this comment

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

Copy link
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます、last_nodeやprevious_nodeで考えてみます。

## Step 2
### 学んだこと
- List.reverese()で一発で逆順にしてくれる
- Stackを使う方法、再帰を使う方法(https://github.com/goto-untrapped/Arai60/pull/27/files/14646ec0859dd9411e6983bf6c63e6f15a1f9f32#r1638693522)、
切断して繋ぐ方法、後ろから繋いでいく方法があった。後ろから繋いでいく方法が短くて綺麗。こちらの方が一通りやられている: https://github.com/ichika0615/arai60/pull/6/files
Copy link

Choose a reason for hiding this comment

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

Memory Limit Exceeded のヒントはこれです。


## Step 3
### コメント
- 切断してから繋ぐやり方の理解が怪しい(過去の問題のPRで指摘され中)のでこれで書いてみる
Copy link

Choose a reason for hiding this comment

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

stack.append(scan)
scan = scan.next

sentinel = ListNode(0, scan)
Copy link

Choose a reason for hiding this comment

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

sentinel.valは使わないので、わざわざ指定せずにsentinel = ListNode(next=scan)でいいんじゃないでしょうか?

https://docs.python.org/3/glossary.html#term-argument

Copy link

Choose a reason for hiding this comment

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

そもそも、この scan は必ず None ではないでしょうか。

Copy link
Owner Author

Choose a reason for hiding this comment

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

最後のnodeで止まっているつもりで書いていた様です...(し、その後stack[-1]をnextにしているしでぐちゃぐちゃですね...)。ありがとうございます。

わざわざ指定せずにsentinel = ListNode(next=scan)でいいんじゃないでしょうか?
今度からはこうしてみます、ありがとうございます。

stack = []

while scan:
stack.append(scan)

Choose a reason for hiding this comment

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

私も最初、よく考えずにノードをスタックにそのまま格納して書いて、MLEでした。
ノードの値の情報だけ抽出してスタックに格納(->その後取り出しながらnewノードを編んでいく流れ)する方法にシフトしたら、解決しました。

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.

4 participants