From ebfef335b41b3f78ed1f453ee72b2ad288181f6a Mon Sep 17 00:00:00 2001 From: yus-yus Date: Mon, 3 Feb 2025 12:06:35 +0900 Subject: [PATCH 1/2] 82. Remove Duplicates from Sorted List II MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 問題:https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/ --- 82.Remove_Duplicates_from_sorted_List_II.md | 143 ++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 82.Remove_Duplicates_from_sorted_List_II.md diff --git a/82.Remove_Duplicates_from_sorted_List_II.md b/82.Remove_Duplicates_from_sorted_List_II.md new file mode 100644 index 0000000..8cfb04a --- /dev/null +++ b/82.Remove_Duplicates_from_sorted_List_II.md @@ -0,0 +1,143 @@ +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を使うという発想がなかった +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) + unique = dummy + scan = head + + 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 + + return dummy.next +``` + + From d2887be7c3eca127c309e9c526edfb1b37f6aae4 Mon Sep 17 00:00:00 2001 From: yus-yus Date: Tue, 4 Feb 2025 13:38:47 +0900 Subject: [PATCH 2/2] Add files via upload --- 82.Remove_Duplicates_from_sorted_List_II.md | 75 +++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/82.Remove_Duplicates_from_sorted_List_II.md b/82.Remove_Duplicates_from_sorted_List_II.md index 8cfb04a..0df690d 100644 --- a/82.Remove_Duplicates_from_sorted_List_II.md +++ b/82.Remove_Duplicates_from_sorted_List_II.md @@ -140,4 +140,79 @@ class Solution: 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 +``` +