-
Notifications
You must be signed in to change notification settings - Fork 0
82. Remove Duplicates from Sorted List II #6
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,117 @@ | ||
| ##step1 | ||
|
|
||
| - 答えになる連結リストを空で用意しておいて、重複しているやつを除くのでnodeを精査した上でokになったら、末尾に足していく方針が自然だと思った | ||
| - 精査する際には調べているNodeの値と、次のNodeの値を比較して異なっていた場合調べているNodeは末尾に追加していいNodeとする(条件1) | ||
| - これではダメで1,2,2,3 の場合に2回目の2を通してしまう | ||
| - 最後に出てきたNodeの値を保持しておいて現在のNodeの値と比較し異なるという条件も必要(条件2) | ||
| - headは最初に出てきた時に保持しておきたい | ||
| - 最後は今まで出てきた数字と異なっていたら足すようにする | ||
| - 最後だけ別で処理するの綺麗じゃない気がする | ||
| - 末尾を特別に処理するのではなく,条件1を次のNodeが存在しない場合はTrueとすれば良さそう | ||
| - 条件2を満たさない場合は全てダメなのでこっちを先に処理した方が綺麗になりそう | ||
| - 同じ変数名を使い回したらだめかもしれない | ||
| - 下記のように書きたいが初回のheadのnextが繋がっていかない | ||
| ``` | ||
| class Solution: | ||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| targetNode = head | ||
| distinctNumNode = None | ||
| distinctNumNodeHead = None | ||
| lastVal = -float("inf") | ||
|
|
||
| while targetNode: | ||
| if targetNode.val != lastVal: | ||
| if targetNode.next is None or targetNode.val != targetNode.next.val: | ||
| distinctNumNode = ListNode(targetNode.val) | ||
| # headが見つかっていない場合はheadに保持しておく | ||
| if distinctNumNodeHead is None: | ||
| distinctNumNodeHead = distinctNumNode | ||
| else: | ||
| distinctNumNode.next = ListNode(targetNode.val) | ||
| distinctNumNode = distinctNumNode.next | ||
| lastVal = targetNode.val | ||
| targetNode = targetNode.next | ||
|
|
||
| return distinctNumNodeHead | ||
| ``` | ||
| したでheadから繋がるようになったが1,2,2の時に1,2,2のWAが出る、 | ||
| ``` | ||
| class Solution: | ||
| def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: | ||
| targetNode = head | ||
| lastVal = -float("inf") | ||
| distinctNumNodeHead = None | ||
|
|
||
| while targetNode: | ||
| if targetNode.val != lastVal: | ||
| if targetNode.next is None or targetNode.val != targetNode.next.val: | ||
| # headが見つかっていない場合はheadに保持しておく | ||
| if distinctNumNodeHead is None: | ||
| distinctNumNode = targetNode | ||
| distinctNumNodeHead = targetNode | ||
| else: | ||
| distinctNumNode.next = targetNode | ||
| distinctNumNode = distinctNumNode.next | ||
| lastVal = targetNode.val | ||
| targetNode = targetNode.next | ||
|
|
||
| return distinctNumNodeHead | ||
| ``` | ||
|
|
||
| 変数で値がどの時点でどこまで保持されているかの理解が浅く、nodeをうまく繋げられていない | ||
| 上でdistinctNumNodeHead.next = Noneとするとheadから繋がらない😭😭😭 | ||
|
|
||
| 一回他の人のコードを読んだ | ||
| https://github.com/Hiroto-Iizuka/coding_practice/pull/4/files | ||
| 僕は答えのheadが何になるかわからなかったのでdistinctNumNodeHeadをNoneで初期化して、最初のnodeが見つかった時に入れるようにしたが、最初に答えを保持するための連結リストを作って最後に最初に作った連結リストの.nextから返すのはいいアイデアだと思った | ||
| 答えのheadかどうかで場合分けする必要がなくなるので処理が楽になる | ||
|
|
||
| 一旦自分の解放の延長線上でどこが悪いのかをChatGPTできいた | ||
| ``` | ||
| if distinctNumNodeTail: | ||
| distinctNumNodeTail.next = None | ||
| ``` | ||
| 付け替えた後に、元々付け替えたNodeには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. これ要するに不変条件はなにかということです。 |
||
|
|
||
| ##step2 | ||
|
|
||
| 一旦、dummyを定義してreturn dummy.nextで書き換える | ||
| 自分の考えかたを再整理 | ||
| - 出てきた最後の値と現在調べているnodeの値を比較して異なっていたらokでそれ以外はng | ||
| - 上記の条件に追加して次のNodeが存在しない場合or次のNodeと現在調べているnodeの値が異なっていたらok | ||
| - 処理が終わった後のnodeで.nextをNoneにする | ||
|
|
||
| 改めて他の人のコードを見る | ||
| https://github.com/Hiroto-Iizuka/coding_practice/pull/4/files | ||
| 正直何をしているかよくわからなかった | ||
| - 連結リストのでのつながりみたいなのが追えず、、、 | ||
| https://github.com/tNita/arai60/pull/5/files | ||
| こちらの方のコードは読めた | ||
| やり方が似ていたから? | ||
| こちらの方についていたコメントで下記のやり取りは勉強になった。 | ||
| 処理済みか処理対象なのかを変数名で表現できていると読みやすくなるので今後は意識的にやっていきたい。 | ||
| resultの他にfilterdとか(自分の場合は今回無意識にdistinctとしたが)をつけるようにしたい | ||
| ``` | ||
| tail は処理済みのノードを繋げていく先だということが、名前に情報をもう少し付け足せると親切に思いました(中盤で初めてそうだと分かる。それまでは node とセットで探索につかうポインタなのかな?とも思いました) | ||
|
|
||
| 確かにそう見えますね。ご指摘ありがとうございます。 | ||
| 以下のようにすると探索には使わないよということがはっきりしますかね。 | ||
| result_dummy = ListNode() | ||
| result_tail = result_dummy | ||
| node = head | ||
| ``` | ||
| https://github.com/mamo3gr/arai60/pull/4/files | ||
| こちらの方のコードを読んだ | ||
| skip_toとかlast_fixedのような変数名はわかりやすかった | ||
| 連結リストあんまり慣れてない自分にとっては気にするnodeがlast_fixedと.nextと.next.nextの3つあってlast_fixed.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. https://1kohei1.com/leetcode/ からリンクされている解説動画が分かりやすかったです。
Owner
Author
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. ありがとうございます。 |
||
|
|
||
| 自分はwhileが苦手かもしれない | ||
| 自分では他の選択肢がある場合は極力書かないようにしているので出てきた時頭の中でシミュレーションがうまく動かない | ||
|
|
||
| 一旦100%理解できてはいないが一旦自分の解法で3回書いてみる。 | ||
| 1周した後にまた戻ってくるようにしたい | ||
|
|
||
|
|
||
| ##step3 | ||
|
|
||
| step2で修正したコードを3回書くことで自分の頭で整理した方法をコードで表現するという部分は頭のリソースをそれほど使わずにできたように感じる | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # | ||
| # @lc app=leetcode id=82 lang=python3 | ||
| # | ||
| # [82] Remove Duplicates from Sorted List II | ||
| # | ||
|
|
||
| # @lc code=start | ||
| # 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]: | ||
| targetNode = head | ||
| lastVal = -float("inf") | ||
| distinctNumNodeHead = None | ||
| distinctNumNodeTail = None | ||
|
|
||
| while targetNode: | ||
| if targetNode.val != lastVal: | ||
| if targetNode.next is None or targetNode.val != targetNode.next.val: | ||
| # headが見つかっていない場合はheadに保持しておく | ||
| if distinctNumNodeHead is None: | ||
| distinctNumNodeHead = targetNode | ||
| distinctNumNodeTail = targetNode | ||
| else: | ||
| distinctNumNodeTail.next = targetNode | ||
| distinctNumNodeTail = distinctNumNodeTail.next | ||
| lastVal = targetNode.val | ||
| targetNode = targetNode.next | ||
|
|
||
| if distinctNumNodeTail: | ||
| distinctNumNodeTail.next = None | ||
|
|
||
| return distinctNumNodeHead | ||
|
|
||
|
|
||
| # @lc code=end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # | ||
| # @lc app=leetcode id=82 lang=python3 | ||
| # | ||
| # [82] Remove Duplicates from Sorted List II | ||
| # | ||
|
|
||
| # @lc code=start | ||
| # 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() | ||
| distinctNode = dummy | ||
| lastVal = -float("inf") | ||
| targetNode = head | ||
|
|
||
| while targetNode: | ||
| if targetNode.val != lastVal: | ||
| if targetNode.next is None or targetNode.val != targetNode.next.val: | ||
| distinctNode.next = targetNode | ||
| distinctNode = distinctNode.next | ||
|
|
||
| lastVal = targetNode.val | ||
| targetNode = targetNode.next | ||
|
|
||
| distinctNode.next = None | ||
|
|
||
| return dummy.next | ||
|
|
||
|
|
||
| # @lc code=end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # | ||
| # @lc app=leetcode id=82 lang=python3 | ||
| # | ||
| # [82] Remove Duplicates from Sorted List II | ||
| # | ||
|
|
||
| # @lc code=start | ||
| # 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() | ||
| distinctNode = dummy | ||
| targetNode = head | ||
| lastVal = -float("inf") | ||
|
|
||
| while targetNode: | ||
| if targetNode.val != lastVal: | ||
| if targetNode.next is None or targetNode.val != targetNode.next.val: | ||
| distinctNode.next = targetNode | ||
| distinctNode = distinctNode.next | ||
|
|
||
| lastVal = targetNode.val | ||
| targetNode = targetNode.next | ||
|
|
||
| distinctNode.next = None | ||
|
|
||
| return dummy.next | ||
|
|
||
|
|
||
| # @lc code=end |
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.
こちらのコメントをご参照ください。
tNita/arai60#3 (comment)
Uh oh!
There was an error while loading. Please reload this page.
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.
こちら元々の関数名がcamelCaseだったので踏襲していたのですが、元々Pythonではsnake_caseが一般的と私も認識しており、実際のコーディング面接の機会になった際に慣れでcamelCaseで書いてしまうと不要な問答が生じてしまいそうなので今後snake_caseで書くようにいたします。