-
Notifications
You must be signed in to change notification settings - Fork 0
83. Remove Duplicates from Sorted List #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,82 @@ | ||
# step1 | ||
```python | ||
class Solution: | ||
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
copy = head | ||
while copy and copy.next: | ||
if copy.val == copy.next.val: | ||
copy.next = copy.next.next | ||
else: | ||
copy = copy.next | ||
return head | ||
``` | ||
#### 思考ログ | ||
- おおよそ解法は思いついたが時間内にコードを書けなかったのでaraiさんの解法を確認 | ||
- 現在の値と次の値を比較するところをisで書いたが今回の場合アドレスの一致ではなく値の一致を見ないとダメなので==にしないとダメ | ||
|
||
# step2 | ||
```python | ||
class Solution: | ||
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
copy = head | ||
while copy and copy.next: | ||
if copy.val == copy.next.val: | ||
copy.next = copy.next.next | ||
continue | ||
copy = copy.next | ||
return head | ||
``` | ||
再帰でも解いてみる | ||
```python | ||
class Solution: | ||
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
if not head or not head.next: | ||
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. あくまで参考にはなりますが、Noneとの比較は 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. あ、これは前回指摘されたところ・・・ |
||
return head | ||
if head.val == head.next.val: | ||
head = self.deleteDuplicates(head.next) | ||
else: | ||
head.next = self.deleteDuplicates(head.next) | ||
return head | ||
``` | ||
#### 思考ログ | ||
- 計算量 | ||
- time complexity:o(n) | ||
- space complexity:o(1) | ||
- 与えられたオブジェクトに破壊的な変更を行うのは実務ではあまりやらないので違和感があったが、コーディングテストではその辺りは気にしないでいい? | ||
- pythonの変数から変数への代入は参照渡しになっている | ||
- pythonのcopyについて調べてみる https://docs.python.org/ja/3/library/copy.html | ||
- A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original. | ||
- A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original. | ||
- deep copyを使えば与えられたオブジェクトの破壊的な変更は防げそう | ||
- 過去解いた人のPRを見てみる | ||
- 再帰で解く方法もあるそう | ||
- 普段あまり再帰でコードを書く機会がないが再帰でしか書けないコード以外で再帰を使う意味はあるのか | ||
- 個人的には再帰に慣れていないからか読みにくい | ||
- nodchipさんのコメントでも以下のようにあった | ||
>あくまで個人的な意見なのですが、ループと再帰で同じ処理が実装できる場合は、ループのほうが読んでいて認知負荷が低いように思います。個人的には step2 の回答のほうが好みです。 | ||
Comment on lines
+52
to
+56
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. 感想みたいなコメント失礼します。
僕自身が「ループと関数なら、関数の方がわかりやすい」と感じていたので、「再帰に慣れていないからか読みにくい」というコメントが学びになります。ありがとうございます。 関数のデメリットとして「読み出し回数上限」や「関数呼び出しのオーバーヘッドがある」ため、どちらでもいいなら、ループを採用していいように思います。(チームメンバーに合わせる前提で。) |
||
- 再帰での解法についてodaさんが例え話で解説していた。他のところでも自然言語で説明するということがよく挙げられているが、自分と専門家集団との差の一つはここにあるのかもしれない | ||
- 変数名に対するodaさんのコメント | ||
- >本当に上から読んでいって明らかならば node だけでもいいと思うんですよね。読み手に何を伝えたいか次第です。for i in range(len(array)): と書かれていたら、添字の配列であろうとほぼ確信して次にいけるわけです。これが長くても迷彩か擬態にしかなりません。 | ||
- 変数名あまり考えずにわかりやすければと長くつけることが多いが、長いことがノイズになることもある。 | ||
- 命名については過去のPRでもよく議論されているがこれはコーディングテストでも重要なポイントなのか、単に突っ込みやすいからなのか | ||
- hayashi-ayさんのコメントにあった以下のやり方だと、elseがなくなりよりシンプルにできる | ||
- >正常系では、1回のループでノードが1つ進むとするとif文はcontinueして、elseを消すのもありかもしれないです。 | ||
- この書き方でシンプルになったがどちらの方がわかりやすいのかは人によるかもしれない | ||
- 議論されている箇所があった(https://github.com/tarinaihitori/leetcode/pull/3/files#r1808004503)、自分としても趣味の範囲という気がする | ||
- pythonにはセイウチ演算子なるものがあり代入式が使えるそう、ただ認知負荷が高い気がする。 | ||
- https://peps.python.org/pep-0572/ | ||
# step3 | ||
```python | ||
class Solution: | ||
def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
copy = 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. 手順はわかりやすくていいと思います。
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. 今回の使い方だとcurrentとかが適切だったかもしれないですね。 |
||
while copy and copy.next: | ||
if copy.val == copy.next.val: | ||
copy.next = copy.next.next | ||
else: | ||
copy = copy.next | ||
return head | ||
``` | ||
#### 思考ログ | ||
- コード1行1行声に出し誰かに説明しながらコードを解いてみた | ||
- 他の人のコードを見る中で再帰やelse無しの書き方を知ったが、結局単純なif-elseの書き方が口頭で説明しやすかった |
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.
copy は標準ライブラリーにある名前なので、できれば被せたくないです。
https://docs.python.org/3/library/copy.html
あとから使いたくなるかもしれないし、こちらを指していると勘違いするかもしれないからです。
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.
たしかに、標準ライブラリと被る点は考慮漏れでした。
currentが適切だったかなと考えています