Conversation
|
|
||
| return sentinel.next | ||
| ``` | ||
| - 他の人の回答をみてると全部のnextの情報を繋ぐのをやめてメモリを節約するとMemoryLimitに収まるらしいので書いてみる 。printしてみるとリストの各要素がnextの果てまで記録していて、空間計算量がO(N^2)になっていた様で、全く気づいてなかった。 |
There was a problem hiding this comment.
これは、二重に間違えています。試しに、
reversed.next = None
return sentinel.nextというふうに、return の上に一行足してみましょう。これで動くはずです。
そのうえで、もう一回考察してみて下さい。
There was a problem hiding this comment.
試してみたら動きました。なるほど...。
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という語感から空間計算量に問題があるという先入観を持ってしまったのだと思います。)。
There was a problem hiding this comment.
理解を一応確認します。最後に pop してきたものの next がその一つ前のやつになっているので、最後の2要素がループになっています。
Memory Limit Exceeded になるのは、おそらく出力を検証している部分が出力をリストに直してから結果を検証しています。そして、そこが無限ループに陥っています。
ここで得られる教訓は、仕事を引き継ぐときに何を引き継いでいるかを意識しようということ、です。
There was a problem hiding this comment.
最後に pop してきたものの next がその一つ前のやつになっているので、最後の2要素がループになっています
これは理解できておりました。
出力を検証している部分が出力をリストに直してから結果を検証しています。
具体的な検証の仕方のイメージはついておらず、この推測は立っておりませんでした。
ここで得られる教訓は、仕事を引き継ぐときに何を引き継いでいるかを意識しようということ、です。
ノード1つ分を処理し終えた時にどこまで仕事が終わっているか認識が甘かったために、最後の要素が1つ前の要素を指したままでループを形成してしまったことに気づけなかったものと認識しています。その意味でおっしゃる教訓はキャッチできていると考えています。
| scan = scan.next | ||
|
|
||
| sentinel = ListNode(0, scan) | ||
| reversed = sentinel |
There was a problem hiding this comment.
reversed は built-in と同じ名前なのでできれば避けたいです。
https://docs.python.org/3/library/functions.html#reversed
https://discord.com/channels/1084280443945353267/1262761766887358557/1324487835557953546
There was a problem hiding this comment.
ありがとうございます、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 |
|
|
||
| ## Step 3 | ||
| ### コメント | ||
| - 切断してから繋ぐやり方の理解が怪しい(過去の問題のPRで指摘され中)のでこれで書いてみる |
There was a problem hiding this comment.
| stack.append(scan) | ||
| scan = scan.next | ||
|
|
||
| sentinel = ListNode(0, scan) |
There was a problem hiding this comment.
sentinel.valは使わないので、わざわざ指定せずにsentinel = ListNode(next=scan)でいいんじゃないでしょうか?
There was a problem hiding this comment.
最後のnodeで止まっているつもりで書いていた様です...(し、その後stack[-1]をnextにしているしでぐちゃぐちゃですね...)。ありがとうございます。
わざわざ指定せずにsentinel = ListNode(next=scan)でいいんじゃないでしょうか?
今度からはこうしてみます、ありがとうございます。
| stack = [] | ||
|
|
||
| while scan: | ||
| stack.append(scan) |
There was a problem hiding this comment.
私も最初、よく考えずにノードをスタックにそのまま格納して書いて、MLEでした。
ノードの値の情報だけ抽出してスタックに格納(->その後取り出しながらnewノードを編んでいく流れ)する方法にシフトしたら、解決しました。
次に解く問題:https://leetcode.com/problems/kth-largest-element-in-a-stream/description/