Skip to content

Create 82. Remove Duplicates from Sorted List II.md#4

Open
TrsmYsk wants to merge 1 commit intomainfrom
TrsmYsk-patch-2
Open

Create 82. Remove Duplicates from Sorted List II.md#4
TrsmYsk wants to merge 1 commit intomainfrom
TrsmYsk-patch-2

Conversation

@TrsmYsk
Copy link
Owner

@TrsmYsk TrsmYsk commented Oct 2, 2025

@TrsmYsk
Copy link
Owner Author

TrsmYsk commented Oct 2, 2025

2-2で参考にしたコメントはこちらです。
https://discord.com/channels/1084280443945353267/1195700948786491403/1196701558382018590

Copy link

@nanae772 nanae772 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

お疲れ様です、ステップごとの改善の様子が分かりやすく読みやすかったです。

Comment on lines +81 to +84
def skip_duplicates(node):
while node.next is not None and node.next.val == node.val:
node.next = node.next.next
return node.next
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

単に重複を飛ばすだけならnode.nextを繋ぎかえていくのではなく、nodeを動かしていく方法のほうが分かりやすいかなと感じました。
nextを繋ぎ変えないのでこの関数の中では副作用が無くなり、そういった点でも良いかなと思います。

Suggested change
def skip_duplicates(node):
while node.next is not None and node.next.val == node.val:
node.next = node.next.next
return node.next
def skip_duplicates(node):
duplicated_val = node.val
while node is not None and node.val == duplicated_val:
node = node.next
return node

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修正後の方がいいですね。手抜きして関数化する前のコードをそのまま関数のコードに流用しておりました。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nodeを動かしていく方法のほうが分かりやすいかなと感じました

同感です。修正後の方が私も良いと思います。

while node.next is not None and node.next.val == node.val:
node.next = node.next.next
return node.next
dummy = ListNode(next = head)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8ではキーワード引数への代入演算子の前後にはスペースを入れないことになっています。ご参考まで。

Don’t use spaces around the = sign when used to indicate a keyword argument, or when used to indicate a default value for an unannotated function parameter:

https://peps.python.org/pep-0008/#other-recommendations

while node.next is not None and node.next.val == node.val:
node.next = node.next.next
return node.next
dummy = ListNode(next = head)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inner functionの定義の後には空行を入れたいなと思いましたが、好みかもしれません。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inner functionの定義の後には空行を入れたいなと思いました

同じように感じました

node = dummy
while node.next is not None and node.next.next is not None:
if node.next.val == node.next.next.val:
copy = node.next
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copyモジュールがあるので、copyという変数名は避けたほうがよいかもしれません。

Comment on lines +85 to +94
dummy = ListNode(next = head)
latest_unique = dummy
checking = latest_unique.next
while checking is not None and checking.next is not None:
if checking.val != checking.next.val:
latest_unique = checking
checking = latest_unique.next
continue
latest_unique.next = skip_duplicates(checking)
checking = latest_unique.next

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

latest_uniquechecking の責務が混ざって見えます。
dummy/latest_unique は「確定済みリスト」、checking は「未確定リストの走査」に役割分担し、latest_unique.next は常に None に保つ不変条件にすると、意図が明確になります。下記のようにすると、ユニーク確定時だけ連結し、それ以外では確定側に触れません。

class Solution:
    def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
        def skip_duplicates(node: ListNode) -> Optional[ListNode]:
            while node.next is not None and node.next.val == node.val:
                node.next = node.next.next
            return node.next

        dummy = ListNode()          # 確定済みリストの番兵
        latest_unique = dummy       # その末尾。常に latest_unique.next は None
        checking = head             # 未確定側の走査ポインタ

        while checking is not None:
            # 直後が別値 or 末尾ならユニーク
            if checking.next is None or checking.val != checking.next.val:
                latest_unique.next = checking   # 確定側に連結
                latest_unique = checking        # 末尾を更新
                checking = checking.next        # 未確定側を先に進める
                latest_unique.next = None       # 不変条件: ここで切断
            else:
                # 重複ブロックは確定側に触れずスキップ
                checking = skip_duplicates(checking)

        return dummy.next

Copy link
Owner Author

@TrsmYsk TrsmYsk Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ご指摘の通りlatest_uniquecheckingの役割を分け切れていなかったです。番兵というテクニックを初めて知りました。


```
## 2-2
- 2-1のコードをさらに整理。参考にした議論はdiscordのリンクを保存してなかったので引用できないが、小田さんがいろいろ突っ込みを入れていて19個目のつっこみで条件式を色々と変形していたあたりを参考にした。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dummy = ListNode(next = head)
node = dummy
while node.next is not None and node.next.next is not None:
if node.next.val == node.next.next.val:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一般にネストを浅くしたほうが読みやすくなる傾向があります。真偽を逆にして、ネストを浅くするとよいと思います。

if node.next.val != node.next.next.val:
    continue

@TrsmYsk TrsmYsk closed this Oct 11, 2025
@TrsmYsk TrsmYsk deleted the TrsmYsk-patch-2 branch October 11, 2025 02:01
@TrsmYsk TrsmYsk restored the TrsmYsk-patch-2 branch October 11, 2025 02:05
@TrsmYsk TrsmYsk reopened this Oct 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants