-
Notifications
You must be signed in to change notification settings - Fork 0
82. Remove Duplicates from Sorted List II #4
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,218 @@ | ||||||||||||||||||||||||||||||||||||||||
| 1st. | ||||||||||||||||||||||||||||||||||||||||
| 二つのnodeを持って置く。 | ||||||||||||||||||||||||||||||||||||||||
| 前を進むnodeが今のnodeと次のnodeのvalを比べて | ||||||||||||||||||||||||||||||||||||||||
| * 等しいとき、前のnodeのみを一つ進める | ||||||||||||||||||||||||||||||||||||||||
| * 等しくない時、前のnodeと後ろのnodeに前のnodeから一つ進んだnodeを入れる | ||||||||||||||||||||||||||||||||||||||||
| をすればいけると考えたがうまく実装出来なかったため解答を見た | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| # Definition for singly-linked list. | ||||||||||||||||||||||||||||||||||||||||
| # class ListNode: | ||||||||||||||||||||||||||||||||||||||||
| # def __init__(self, val=0, next=None): | ||||||||||||||||||||||||||||||||||||||||
| # self.val = val | ||||||||||||||||||||||||||||||||||||||||
| # self.next = next | ||||||||||||||||||||||||||||||||||||||||
| class Solution: | ||||||||||||||||||||||||||||||||||||||||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||||||||||||||||||||||||||||||||||||||||
| dummy_node = ListNode(0, head) | ||||||||||||||||||||||||||||||||||||||||
| back_node = dummy_node | ||||||||||||||||||||||||||||||||||||||||
| node = head | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| while node: | ||||||||||||||||||||||||||||||||||||||||
| while node.next and node.val == node.next.val: | ||||||||||||||||||||||||||||||||||||||||
| node = node.next | ||||||||||||||||||||||||||||||||||||||||
| # この時点でnodeのvalとnode.next.valは違う(境目) | ||||||||||||||||||||||||||||||||||||||||
| # ここで、 | ||||||||||||||||||||||||||||||||||||||||
| # back_nodeの次が今のnode ⇔ node.valは重複しないnode(その値を持つのは一つだけ) | ||||||||||||||||||||||||||||||||||||||||
| # その他 ⇔ 今のnode.valは重複するnodeなのでback_nodeを次(node.next)までもっていく | ||||||||||||||||||||||||||||||||||||||||
| if back_node.next == node: | ||||||||||||||||||||||||||||||||||||||||
| back_node = back_node.next | ||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||
| back_node.next = node.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| node = node.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return dummy_node.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
| まずdummy 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. dummy を使わなくても分岐が少し増えるだけですね。使うことはいいんですが、使わないコードも書けると思って使ってください。
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. コメントありがとうございます。
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. 4th.で実装してみました。 |
||||||||||||||||||||||||||||||||||||||||
| headが変更される可能性がある今回のような場合はdummy nodeをせっていすることでそのような場合を考慮せずにすむ | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| 2nd. | ||||||||||||||||||||||||||||||||||||||||
| (https://github.com/SanakoMeine/leetcode/pull/5/files) を参考に一番しっくりくる解答は以下だった。 | ||||||||||||||||||||||||||||||||||||||||
| pointとしては重複があるかをまずはifでみてからwhileで進めることで、これによって重複がないときとif-elseでキレイに分けて書ける。 | ||||||||||||||||||||||||||||||||||||||||
| 始めの | ||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| if not scan.next: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = scan | ||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
| は下のifを | ||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| if scan.next and scan.val == scan.next.val: | ||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
| にすることでまとめられるが、こちらの方が分かりやすく感じたのでこちらを採用した | ||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| # Definition for singly-linked list. | ||||||||||||||||||||||||||||||||||||||||
| # class ListNode: | ||||||||||||||||||||||||||||||||||||||||
| # def __init__(self, val=0, next=None): | ||||||||||||||||||||||||||||||||||||||||
| # self.val = val | ||||||||||||||||||||||||||||||||||||||||
| # self.next = next | ||||||||||||||||||||||||||||||||||||||||
| class Solution: | ||||||||||||||||||||||||||||||||||||||||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||||||||||||||||||||||||||||||||||||||||
| dummy = ListNode(0, head) | ||||||||||||||||||||||||||||||||||||||||
| unique = dummy | ||||||||||||||||||||||||||||||||||||||||
| scan = head | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| while scan: | ||||||||||||||||||||||||||||||||||||||||
| # 最後のnode | ||||||||||||||||||||||||||||||||||||||||
| if not scan.next: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = scan | ||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| # 重複が一つでもあるとき最後の重複部分まですべて飛ばす | ||||||||||||||||||||||||||||||||||||||||
| if scan.val == scan.next.val: | ||||||||||||||||||||||||||||||||||||||||
| while scan.next and scan.val == scan.next.val: | ||||||||||||||||||||||||||||||||||||||||
| scan.next = scan.next.next | ||||||||||||||||||||||||||||||||||||||||
| unique.next = scan.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| # 重複がないならuniqueに追加する | ||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = scan | ||||||||||||||||||||||||||||||||||||||||
| unique = scan | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| # 一つ進める | ||||||||||||||||||||||||||||||||||||||||
| scan = scan.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return dummy.next | ||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| 再帰を使った解答もあった | ||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| # Definition for singly-linked list. | ||||||||||||||||||||||||||||||||||||||||
| # class ListNode: | ||||||||||||||||||||||||||||||||||||||||
| # def __init__(self, val=0, next=None): | ||||||||||||||||||||||||||||||||||||||||
| # self.val = val | ||||||||||||||||||||||||||||||||||||||||
| # self.next = next | ||||||||||||||||||||||||||||||||||||||||
| class Solution: | ||||||||||||||||||||||||||||||||||||||||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||||||||||||||||||||||||||||||||||||||||
| if not head or not head.next: | ||||||||||||||||||||||||||||||||||||||||
| return head | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if head.val != head.next.val: | ||||||||||||||||||||||||||||||||||||||||
| head.next = self.deleteDuplicates(head.next) | ||||||||||||||||||||||||||||||||||||||||
| return head | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| while head.next and head.val == head.next.val: | ||||||||||||||||||||||||||||||||||||||||
| head = head.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return self.deleteDuplicates(head.next) | ||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
| 再帰の呼び出し回数としてはすべてのnodeのvalが異なるとき最も呼び出されて、(node数-1)回呼び出される | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| 3rd. | ||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| # Definition for singly-linked list. | ||||||||||||||||||||||||||||||||||||||||
| # class ListNode: | ||||||||||||||||||||||||||||||||||||||||
| # def __init__(self, val=0, next=None): | ||||||||||||||||||||||||||||||||||||||||
| # self.val = val | ||||||||||||||||||||||||||||||||||||||||
| # self.next = next | ||||||||||||||||||||||||||||||||||||||||
| class Solution: | ||||||||||||||||||||||||||||||||||||||||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||||||||||||||||||||||||||||||||||||||||
| dummy = ListNode(0, 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. 自分なら
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. コメントありがとうございます。 |
||||||||||||||||||||||||||||||||||||||||
| unique = dummy | ||||||||||||||||||||||||||||||||||||||||
| scan = 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. scanという単語は、https://dictionary.cambridge.org/dictionary/english/scan によれば、全体をくまなくみること、みる動作を意味するみたいです。 node = head
while node is not None:
...
node = node.nextという全体の構造を意味していると感じます。関数名としては適切かもしれませんが、scanしている対象はListNodeなので、nodeでいいと思います。
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 scan: | ||||||||||||||||||||||||||||||||||||||||
| if not scan.next: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = scan | ||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if scan.val == scan.next.val: | ||||||||||||||||||||||||||||||||||||||||
| while scan.next and scan.val == scan.next.val: | ||||||||||||||||||||||||||||||||||||||||
| scan.next = scan.next.next | ||||||||||||||||||||||||||||||||||||||||
| unique.next = scan.next | ||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = scan | ||||||||||||||||||||||||||||||||||||||||
| unique = scan | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| scan = sca.next | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+130
to
+138
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
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. 日本語でこの解法を説明する時に、「scan.valとscan.next.valの値が違うならuniqueにscanを追加して、unique, scan進めます。同じなら、scan.valがその値にならなくなるまでscanを進め、uniqueの末尾にscanを追加します」みたいに分けて書くのが自然だと思います。 L138のように合流させるような説明は読んでいて複雑に感じます。
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. 自分のコードは、
という風にみていて、どちらもif-else終了時に、 しかし、確かにこちらの方が素直な実装に感じます。
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. 4th.で実装してみました。 |
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return dummy.next | ||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| 4th. | ||||||||||||||||||||||||||||||||||||||||
| reviewを参考に書き直した | ||||||||||||||||||||||||||||||||||||||||
| コメントをくださったみなさんありがとうございました。 | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| * dummy_headを用いない方法 (https://discord.com/channels/1084280443945353267/1334041281902547036/1335906471111688212) | ||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| # Definition for singly-linked list. | ||||||||||||||||||||||||||||||||||||||||
| # class ListNode: | ||||||||||||||||||||||||||||||||||||||||
| # def __init__(self, val=0, next=None): | ||||||||||||||||||||||||||||||||||||||||
| # self.val = val | ||||||||||||||||||||||||||||||||||||||||
| # self.next = next | ||||||||||||||||||||||||||||||||||||||||
| class Solution: | ||||||||||||||||||||||||||||||||||||||||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||||||||||||||||||||||||||||||||||||||||
| # headが重複するnodeの場合 | ||||||||||||||||||||||||||||||||||||||||
| # 重複しない要素が先頭になるまで進める | ||||||||||||||||||||||||||||||||||||||||
| while head and head.next and head.val == head.next.val: | ||||||||||||||||||||||||||||||||||||||||
| while head.next and head.val == head.next.val: | ||||||||||||||||||||||||||||||||||||||||
| head = head.next | ||||||||||||||||||||||||||||||||||||||||
| head = head.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| # ここからの実装はheadが重複しない要素なので | ||||||||||||||||||||||||||||||||||||||||
| # dummy_headのようにheadを使うことが出来る | ||||||||||||||||||||||||||||||||||||||||
| # ただしheadがNoneのときがあるので注意 | ||||||||||||||||||||||||||||||||||||||||
| if not head: | ||||||||||||||||||||||||||||||||||||||||
| return head | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| unique = head | ||||||||||||||||||||||||||||||||||||||||
| node = head.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| while node and node.next: | ||||||||||||||||||||||||||||||||||||||||
| if node.val == node.next.val: | ||||||||||||||||||||||||||||||||||||||||
| while node.next and node.val == node.next.val: | ||||||||||||||||||||||||||||||||||||||||
| node.next = node.next.next | ||||||||||||||||||||||||||||||||||||||||
| unique.next = node.next | ||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = node | ||||||||||||||||||||||||||||||||||||||||
| unique = node | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| node = node.next | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return head | ||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| * より自然言語で流れを説明しやすい t0hsumiさんの解法(https://discord.com/channels/1084280443945353267/1334041281902547036/1335889669476323448) | ||||||||||||||||||||||||||||||||||||||||
| ```Python | ||||||||||||||||||||||||||||||||||||||||
| # Definition for singly-linked list. | ||||||||||||||||||||||||||||||||||||||||
| # class ListNode: | ||||||||||||||||||||||||||||||||||||||||
| # def __init__(self, val=0, next=None): | ||||||||||||||||||||||||||||||||||||||||
| # self.val = val | ||||||||||||||||||||||||||||||||||||||||
| # self.next = next | ||||||||||||||||||||||||||||||||||||||||
| class Solution: | ||||||||||||||||||||||||||||||||||||||||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||||||||||||||||||||||||||||||||||||||||
| dummy_head = ListNode(0, head) | ||||||||||||||||||||||||||||||||||||||||
| unique = dummy_head | ||||||||||||||||||||||||||||||||||||||||
| node = head | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| while node: | ||||||||||||||||||||||||||||||||||||||||
| if not node.next: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = node | ||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if node.val != node.next.val: | ||||||||||||||||||||||||||||||||||||||||
| unique.next = node | ||||||||||||||||||||||||||||||||||||||||
| unique = unique.next | ||||||||||||||||||||||||||||||||||||||||
| node = node.next | ||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| duplicated_value = node.val | ||||||||||||||||||||||||||||||||||||||||
| while node and node.val == duplicated_value: | ||||||||||||||||||||||||||||||||||||||||
| node = node.next | ||||||||||||||||||||||||||||||||||||||||
| unique.next = node | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return dummy_head.next | ||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
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.
backよりfastとslowで前のnodeと後ろ(進みの遅い)nodeを表したらいいかなと思いました。
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.
コメントありがとうございます。
確かに他の皆さんのコードでもbackはあまり見なかった気がするので、一般的な名前にしたいと思います。