-
Notifications
You must be signed in to change notification settings - Fork 0
206. Reverse Linked List #9
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
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,49 @@ | ||
| ## step1 | ||
| - headはnextをNoneに、それ以外はnextを一つ前の要素に変える | ||
| - stackとなっているが、一つ前以外の履歴は保持しなくていいのではないか? | ||
| - 最後に元々のnextがNoneの要素が見つかったらそれをheadにする | ||
| - よりもNoneを見たらdummy.nextに入れてそれをheadにした方がNoneが入ってきた時に場合分けがいらない | ||
| - 実装しようとするとめちゃ頭こんがらがるので一旦整理したい | ||
| - まず一番楽そうなstackでやってみる | ||
| - 全部stackに詰める | ||
| - 詰め終わったら末尾をheadにする | ||
| - popしてnextをstack[-1]にしていき、最後はnextをNoneにする | ||
| - 気になるところ | ||
| - 最初だけ別で処理しているのをやめたい | ||
| - reversed_headがNoneの時(whileの初回)に最後にreversed_head = nodeにすればいいことに気づいた | ||
|
|
||
| ## step2 | ||
| - stackに入れている時に書き換えちゃったらいいのでは!!!!! | ||
| - 頭で整理できておらず、思ったよりすんなり書けない | ||
| - 1. nodeをstackにいれる | ||
| - 2. 元々stackが空の時、入れたnodeのnextはNone,それ以外は入れたnodeのnextはstackの末尾 | ||
| - ここで調査対象のnodeを書き換えてるのでうまくいっていない | ||
| - 書き換えずにうまいことするのはちょっと大変か?(他の人のコード例みて確認する) | ||
| - なので新しいListNode(node.val)を定義すればうまくいく | ||
| - 元のNodeを書き換える場合はメモリ効率が高い | ||
| - 最後にstackの末尾を答える | ||
| - 時間計算量: O(n) | ||
| - 空間計算量: O(n) ほんとはO(1)にできそう | ||
| - 他の人のコードを読んでるが、読みにくいというか入ってこない | ||
| - nodeの挙動と変数の使い方でどこまで影響を与えているのかをイメージするのにかなり脳のリソースを割かれているからな気がする | ||
| - https://github.com/Hiroto-Iizuka/coding_practice/pull/7/files | ||
| - dummyの使い方がいいと思った | ||
| - 最後元がNoneかどうかで場合分けするのできればやめたかったから | ||
| - ただコードが簡潔になるというだけで、処理のわかりやすさ的には場合分けしてた方が良いのかも | ||
| - `一応、この問題の出題意図は、LinkedList でお手玉ができますかということかと思うので、これは出題意図には沿っていないだろうと推測します。`解いてみて感じたが、こういうことだろうと思うので新しいListNodeを定義するのは良くないかも(気をつけないといけない感覚があるのは伝わるかもだが) | ||
| - https://github.com/tNita/arai60/pull/8/files | ||
| - `スタックとして使うのであれば list で十分だと思います。一般に、同じ目的に使えるデータ構造が複数ある場合、その中で一番実装が軽いものを選ぶことが多いように思います。` | ||
| - dequeをstackとして使う人がいるなとは思っていたが、どっちでもいいなら書く量が少ない普通のlist派だった | ||
| - deque派の意見が聞きたいところ | ||
| - https://github.com/mamo3gr/arai60/pull/7/files | ||
| - step1でこんな感じに書けるようになりたいが、実装できなかった | ||
| - forwardに次の処理対象のnodeを取っておく | ||
| - 現在の処理対象のnodeのnextを一つ前の(処理済みの)node(previous)に変える | ||
| - 現在の処理済みのnodeを次のloopのために取っておく(previous) | ||
| - 次のloopのためにnodeにforwardを入れる | ||
| - 最初から処理する方の再帰と再帰でcallStackに積んで(言葉があっているかは怪しい)積み終わったのちに順々に処理しているように見える | ||
| - `関数は基本的に中を読みたくないのです。`なので関数名が長く説明的でも良いみたい | ||
| - headがNoneの時は一番最初にNoneを返した方が最後で場合分けするより実装時に考慮事項が減り楽出し、読んでる時にもListNodeが入っている前提で読めるのでわかりやすい | ||
| - 頭がこんがらがっているので問題をお気に入りしておき再帰はまた今後やる | ||
|
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. 再帰関数は、関数自体はマニュアルだと思って、大量の部下にそのマニュアルをバラマキ、部下同士が仕事を依頼し合うと考えるとできませんかね。 |
||
| ## step3 | ||
| - 一回理解をして、処理をイメージできさえすれば実装は必然的にこうなる感みたいなのがあるが、自分で思いつけないなとも思う | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # | ||
| # @lc app=leetcode id=206 lang=python3 | ||
| # | ||
| # [206] Reverse Linked List | ||
| # | ||
|
|
||
| # @lc code=start | ||
| # Definition for singly-linked list. | ||
| # class ListNode: | ||
| # def __init__(self, val=0, next=None): | ||
| # self.val = val | ||
| # self.next = next | ||
| class Solution: | ||
| def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| node_stack = [] | ||
| node = head | ||
| reversed_head = None | ||
|
|
||
| while node: | ||
| node_stack.append(node) | ||
| node = node.next | ||
|
|
||
| while node_stack: | ||
| node = node_stack.pop() | ||
| if node_stack: | ||
| node.next = node_stack[-1] | ||
| else: | ||
| node.next = None | ||
|
|
||
| if reversed_head is None: | ||
| reversed_head = node | ||
|
|
||
| return reversed_head | ||
|
|
||
|
|
||
| # @lc code=end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # | ||
| # @lc app=leetcode id=206 lang=python3 | ||
| # | ||
| # [206] Reverse Linked List | ||
| # | ||
|
|
||
| # @lc code=start | ||
| # Definition for singly-linked list. | ||
| # class ListNode: | ||
| # def __init__(self, val=0, next=None): | ||
| # self.val = val | ||
| # self.next = next | ||
| class Solution: | ||
| def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| node = head | ||
| previous = None | ||
|
|
||
| while node: | ||
| # 元々のnextをforwardに保持しておく | ||
| forward = node.next | ||
| # 現在の処理対象のnodeのnextを一つ前の処理ずみのnodeに変更 | ||
| node.next = previous | ||
| # 現在処理したnodeを次のloopのために保持 | ||
| previous = node | ||
| # 保持していたnextを戻す | ||
| node = forward | ||
|
|
||
| # 最後に処理ずみのnodeがpreviousに入っているのでpreviousを返す | ||
| return previous | ||
|
|
||
|
|
||
| # @lc code=end |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,27 @@ | ||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||
| # @lc app=leetcode id=206 lang=python3 | ||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||
| # [206] Reverse Linked List | ||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # @lc code=start | ||||||||||||||||||||||||||||
| # Definition for singly-linked list. | ||||||||||||||||||||||||||||
| # class ListNode: | ||||||||||||||||||||||||||||
| # def __init__(self, val=0, next=None): | ||||||||||||||||||||||||||||
| # self.val = val | ||||||||||||||||||||||||||||
| # self.next = next | ||||||||||||||||||||||||||||
| class Solution: | ||||||||||||||||||||||||||||
| def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||||||||||||||||||||||||||||
| node = head | ||||||||||||||||||||||||||||
| previous = None | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| while node: | ||||||||||||||||||||||||||||
| forward = node.next | ||||||||||||||||||||||||||||
| node.next = previous | ||||||||||||||||||||||||||||
| previous = node | ||||||||||||||||||||||||||||
| node = forward | ||||||||||||||||||||||||||||
|
Comment on lines
+19
to
+22
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. ここの複雑なお手玉をいかに分かりやすく書くかが腕の見せどころだと思います。(私もはじめは使っていたのですが)
また、処理単位ごとに空行で分けるとなおわかりよいかもしれません。
Suggested change
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| return previous | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # @lc code=end | ||||||||||||||||||||||||||||
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.
どちらでもいいと思います。List はリアロケーションで遅くなるときがあるので、それが本当に問題になるような場合には deque というくらいですかね。