-
Notifications
You must be signed in to change notification settings - Fork 0
Q2-9 Middle of the Linked List #37
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,133 @@ | ||
| # 2-09_MiddleoftheLinkedList | ||
| Author: WaveAlchemist | ||
| Given the head of a singly linked list, return the middle node of the linked list. | ||
|
|
||
| If there are two middle nodes, return the second middle node. | ||
|
|
||
| # 1st | ||
| 初見では以下の方針で解答 | ||
| - nodeを最後まで(Noneになるまで)進める | ||
| - 最後まで進んだらその時何番目か(node_count)を返す | ||
| - int(node_count / 2 + 1)番目まで最初からnodeを進める | ||
| - nodeの数を計算する関数と希望するnode数nodeを進める関数を作成 | ||
| 解答時間は12min39sでした | ||
| 思いついたアルゴリズムがこれだけだったのでこれで提出しましたが,無駄なことをやっているような気がしています. | ||
|
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. 私はこれが標準的な解答でいいと思います。
Owner
Author
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 | ||
| class Solution: | ||
| def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| def checkNodeNumber(node, node_count): | ||
|
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.
Owner
Author
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. ご指摘の通りかと思います. def checkNodeNumber(node):
node_count = 1 # 1-indexed
while node.next:
node = node.next
node_count += 1
return node_countで良いですね(いちいち外部からnode_countを与えるのはくどいですね(笑)) 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.
leetcode側の表記がアレですが、合わせなくても良いかと。 ご参考:
Owner
Author
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. ありがとうございます |
||
| while node.next: | ||
| node = node.next | ||
| node_count += 1 | ||
| return node_count | ||
| def proceedNode(node, end_node): | ||
|
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.
もっというと、
Owner
Author
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から目的のnodeまで進めるという関数という意図ですので, check_node_numberはnodeの数という意図ですので,この関数で進めるnode数を計算するのであれば関数名は変更したほうがいいですね.check_middle_node_numberとかどうでしょうか? |
||
| node_count = 1 | ||
|
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. 好みの問題かもしれませんが、countが1から始まるのは少し違和感あるかもしれません。(1-indexedとしているの場合、コメントがあると嬉しいかもです。)
Owner
Author
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. ここはnodeの個数という意図でしたので1-indexedです.つまり, head = [3] ならnodeは1つと数えた方が感覚的には理解しやすいかと. |
||
| while node.next and node_count: | ||
|
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.
Owner
Author
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. node_countを減らしていくという発想はなかったです.ありがとうございます def proceed_node(node, num_proceed):
while node.next:
node = node.next
num_proceed -= 1
if num_proceed == 0:
return node
return node |
||
| node = node.next | ||
| node_count += 1 | ||
| if node_count == end_node: | ||
| return node | ||
| return node | ||
| max_node_count = checkNodeNumber(head, 1) | ||
| middle_node_count = int(max_node_count / 2 + 1) | ||
|
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. 自分だったら、型変換を避けるため、
Owner
Author
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. 返答遅くなり申し訳ございません! |
||
| return proceedNode(head, middle_node_count) | ||
| ``` | ||
|
|
||
| # 2nd | ||
| LeetCodeのSolutionsを参照 | ||
| Linked List Cycleで出てきたfastとslowを用いる方法を実装 | ||
| fast.nextがNoneになった時点でfastはmiddle nodeにいるということに留意 | ||
|
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. 確かにこの方法がありましたね。
Owner
Author
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 | ||
| class Solution: | ||
| def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| slow = fast = head | ||
| while fast and fast.next: | ||
| fast = fast.next.next | ||
| slow = slow.next | ||
| return slow | ||
| ``` | ||
|
|
||
| # 3rd | ||
| レビューのコメントをもとに再度構築しました(解法は1stのものをベースにしています) | ||
|
|
||
| - int(max_node_count / 2 + 1) -> max_node_count // 2 + 1 | ||
| - node_count = 1に1-indexedというコメントを付与 | ||
| - checkNodeNumber -> check_node_number, proceedNode -> proceed_node | ||
| - proceed_node内部でnodeを進めるごとにnum_proceedを1ずつ減らすという方法を実装 | ||
|
|
||
| check_node_numberでnodeの数を数える場合 | ||
|
|
||
| ```Python | ||
| class Solution: | ||
| def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| def check_node_number(node): | ||
| node_count = 1 # 1-indexed | ||
| while node.next: | ||
| node = node.next | ||
| node_count += 1 | ||
| return node_count | ||
|
|
||
| def proceed_node(node, num_proceed): | ||
| while node.next: | ||
| node = node.next | ||
| num_proceed -= 1 | ||
| if num_proceed == 0: | ||
| return node | ||
| return node | ||
|
|
||
| max_node_count = check_node_number(head) | ||
| middle_node_count = max_node_count // 2 + 1 | ||
| return proceed_node(head, middle_node_count - 1) | ||
|
|
||
| ``` | ||
|
|
||
| check_node_numberをcheck_middle_node_numberとし,進めるべきnode数(つまり真ん中のnode数)を計算する場合 | ||
| return node_count // 2として,proceed_nodeに代入するのはmiddle_node_countでいいのかも | ||
| (ただ,関数の名前的にはノードの数ということになるので,感覚としては現状がいい気もする。 | ||
| つまり,真ん中のノードの数とノードを進める回数は違うということ) | ||
|
|
||
| ``` Python | ||
| class Solution: | ||
| def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| def check_middle_node_number(node): | ||
| node_count = 1 # 1-indexed | ||
| while node.next: | ||
| node = node.next | ||
| node_count += 1 | ||
| return node_count // 2 + 1 | ||
|
|
||
| def proceed_node(node, num_proceed): | ||
| while node.next: | ||
| node = node.next | ||
| num_proceed -= 1 | ||
| if num_proceed == 0: | ||
| return node | ||
| return node | ||
|
|
||
| middle_node_count = check_middle_node_number(head) | ||
| print(middle_node_count) | ||
| return proceed_node(head, middle_node_count - 1) | ||
| ``` | ||
|
|
||
| 関数を使わない方法も試してみる | ||
| 思ったよりスッキリかけた気がします.nodeを進めるときのwhile文はfor文で書いてもいいかもしれません. | ||
|
|
||
| ``` Python | ||
| class Solution: | ||
| def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| node = head | ||
| node_count = 1 # 1-indexed | ||
| # check node number | ||
| while node.next: | ||
| node = node.next | ||
| node_count += 1 | ||
| # check node number to be proceeded | ||
| num_proceed = node_count // 2 | ||
| # proceed node | ||
| node = head | ||
| for proceed in range(num_proceed, 0, -1): | ||
| node = node.next | ||
| return node | ||
| ``` | ||
Uh oh!
There was an error while loading. Please reload this page.
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.
1st:
個人的には、関数にすると登場人物多くなるのと今回複数同じ処理をするわけではないので、
関数にしない方がスッキリ書ける気がします
・for文でnodeを最後まで進める+node数カウンターを用意する
・node数の半分になるようなカウンター(A)を用意して代入
・while文でAを一つずつ減らしながら、0になるまで進める
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.
2nd:
LinkedListの構造うまく使っていて勉強になりました、、
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.
関数にするいいところは、変数のスコープが限定できるところです。後は程度問題ですね。
https://discord.com/channels/1084280443945353267/1201211204547383386/1215702126945112094
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.
ありがとうございます.関数にしない方法も試してみます