diff --git a/83. Remove Duplicates from Sorted List.md b/83. Remove Duplicates from Sorted List.md new file mode 100644 index 0000000..441150e --- /dev/null +++ b/83. Remove Duplicates from Sorted List.md @@ -0,0 +1,82 @@ + +URL: https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/ + +# Step 1 + +- 実装時間: 3分 +- 時間計算量: O(n) +- 空間計算量: O(1) +- while条件とif条件が似ているのが気になったけど、これ以外の実装は思い付かなかったのでsubmit. + +```python +class Solution: + def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: + current = head + while current is not None: + if current.next is None: + return head + if current.val == current.next.val: + current.next = current.next.next + else: + current = current.next + return head +``` + +# Step 2 + +- 過去のPRを見ていると、再帰Verの話があったので、僕も実装してみる。 + +```python +class Solution: + def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: + if head is None: + return head + current = head + while current.next is not None and current.val == current.next.val: + current = current.next + current.next = self.deleteDuplicates(current.next) + return current +``` + +- 過去のPRにて、末尾再帰最適化の議論を見た。 + - 今回は`current.next`を更新しているので、単純に末尾再帰は出来なさそう。 + - そもそもPythonでの末尾再帰の実装とか条件を知らないことに気づいたので調べてみる。→Pythonにはない。 +https://www.python.jp/news/wnpython311/inline-function.html + + +- Discordを見ていて`current`という変数の命名について無意識についけていたことに気づいた。別の候補として`current_node`や`current_focusing_node`を思いついた。しかし、今回は短い処理であり、今注目しているノードという点は伝わる範囲だと思うので、`current`という変数名を使うことにする。もっと長い処理場合は、より意味のこもった変数名にする。 + +- 過去のコメントより、ifの判定はwhile条件に入れるだけでいいことを理解した。↓改良版。 + +```python +class Solution: + def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: + current = head + while current is not None and current.next is not None: + if current.val == current.next.val: + current.next = current.next.next + else: + current = current.next + return head +``` + +- `current is not None`をループごとに確認するのは冗長だと気づいた。関数の初めに一度確認すれば、あとは確認不要。 + +# Step 3 + +- 時間計算量: O(n) +- 空間計算量: O(1) + +```python +class Solution: + def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: + if head is None: + return None + current = head + while current.next is not None: + if current.val == current.next.val: + current.next = current.next.next + else: + current = current.next + return head +```