82. Remove Duplicates from Sorted List II#38
Conversation
| # 末尾節の古いnextを切る | ||
| unique_groups[-1][0].next = None | ||
|
|
||
| return unique_groups[0][0] |
There was a problem hiding this comment.
こちらのコードは、入力を書き換えていることは認識しておくとよいです。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.gys2docabo9y
There was a problem hiding this comment.
入力を書き換えないのであれば、例えば、以下のように書けます。
from collections import OrderedDict
class Solution:
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
value_to_count = OrderedDict()
while node is not None:
if node.val not in value_to_count:
value_to_count[node.val] = 1
else:
value_to_count[node.val] += 1
node = node.next
dummy = ListNode()
tail = dummy
for value, count in value_to_count.items():
if count == 1:
tail.next = ListNode(value)
tail = tail.next
return dummy.next(nodeを保持する代わりに何個あったかカウントするようにしました。新しいnodeをつくるときは、valueさえあればいいので)
There was a problem hiding this comment.
コード例の提示ありがとうございます。
この関数が使われる状況によりますが、入力を書き換えているかどうかは意識すべきですね
| # 末尾節の古いnextを切る | ||
| unique_groups[-1][0].next = None | ||
|
|
||
| return unique_groups[0][0] |
There was a problem hiding this comment.
元のコードについてですが、dummyを使うと、もう少しシンプルに書けそうです
dummy = ListNode()
tail = dummy
for nodes in value_to_node.values():
if len(nodes) == 1:
tail.next = nodes[0]
tail = tail.next
tail.next = None
return dummy.next| ```py | ||
| class Solution: | ||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| value_to_node = defaultdict(list) |
There was a problem hiding this comment.
一応ですが、Python2.7以降Pyhon3.7以前ならOrdereddictを使うと入れた順番を保持します。
https://pypi.org/project/ordereddict/
There was a problem hiding this comment.
さらに付け加えると、3.7 以降は通常の dict でもデフォルトで挿入順を保持するのが仕様として定められているので基本的には通常の dict を使うのが良いとされているようで、バージョンを意識しながら書けると良さそうです。
Since Python 3.7, dictionaries are ordered by default, so there is usually little need for these functions; prefer PyDict* where possible.
https://docs.python.org/ja/3/c-api/dict.html#ordered-dictionaries
There was a problem hiding this comment.
3.7以降であれば基本的に通常のdictで良さそうですね
| return dummy.next | ||
| ``` | ||
| - こちらは空間計算量: $O(1)$ で済む | ||
| - だいぶ前に(別の問題だが)似た解法を使ったのを思い出した |
There was a problem hiding this comment.
この方針ではソートされていることが前提ですが、元の方針ならソートされていなくてもできる、ということはおさえておきたいですね。
There was a problem hiding this comment.
おっしゃる通り、ソート前提でなく(重複文字列が連続していない)とも使えるような解法を考えていました。
| if current.next and current.val == current.next.val: | ||
| visited_value = current.val | ||
|
|
||
| while current and current.val == visited_value: | ||
| current = current.next | ||
|
|
||
| previous.next = current | ||
| continue | ||
|
|
||
| previous = current | ||
| current = current.next |
There was a problem hiding this comment.
if A:
長い処理
continue
短い処理の形ですが、これだと「長い処理」を読んだあと「短い処理」の部分の条件を把握(思い出す)のに「長い処理」の前の A に遡って条件を確認しないといけなくて(あるいは、「not A の場合どうなるんだろう」、というのを頭に置いたまま「長い処理」を読むので長時間ワーキングメモリを取られる感じがして)個人的にはやや負荷を感じました。
if not A:
短い処理
continue
長い処理のように入れ替えるとより読みやすいかもしれません。
There was a problem hiding this comment.
確かに初見だと、現在の分岐の書き方だとワーキングメモリを喰われますね。ご指摘ありがとうございます。
| previous = sentinel | ||
| current = head |
There was a problem hiding this comment.
previous, current という名前ですが、処理の途中で「previous は置き去りにしたまま current をどんどん進める」ところがあって個人的には少しギャップを感じました。
previous の代わりに unique_tail, saved_tail, tail_so_far などの説明的な名前でもいいのかなと思います。
current は current のままでもいいかもしれませんし、 checking とか単に node とかもいいかもしれません。
There was a problem hiding this comment.
自分だと tail_so_far がより適切だと感じました。ご指摘ありがとうございます。
| ```py | ||
| class Solution: | ||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| value_to_node = defaultdict(list) |
There was a problem hiding this comment.
さらに付け加えると、3.7 以降は通常の dict でもデフォルトで挿入順を保持するのが仕様として定められているので基本的には通常の dict を使うのが良いとされているようで、バージョンを意識しながら書けると良さそうです。
Since Python 3.7, dictionaries are ordered by default, so there is usually little need for these functions; prefer PyDict* where possible.
https://docs.python.org/ja/3/c-api/dict.html#ordered-dictionaries
| value_to_node = defaultdict(list) | ||
| node = head | ||
|
|
||
| while node: |
There was a problem hiding this comment.
こちらのコメントをご参照ください。
ksaito0629/leetcode_arai60#1 (comment)
There was a problem hiding this comment.
コメントの参照ありがとうございます。今回の場合では node is not None の方がより安全だと理解しました。
82. Remove Duplicates from Sorted List II
次回予告: 98. Validate Binary Search Tree