Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions 82/step1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Time: 21:00
Space: O(1)
Time: O(N)

先頭要素も削除されうるため、返すためのダミーノードを用意する。
リスト全体をチェックしていくwhileループと、重複要素を削除するwhileループを入れ子にする。
重複要素はすべて消さないといけないので、判定するためにvalを残す。
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* dummy_head = new ListNode(0, head);
ListNode* current = dummy_head;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

自分は current という名前でもよいと思うのですが、他の方で current という単語にはあまり意味がないため、あえて current という変数名を付ける利点はないという方もいらっしゃいます。 node と付けても良いと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます。
なるほど、currentだけだと違和感があるというのは納得です。

Mike0121/LeetCode#7 (comment)
https://discord.com/channels/1084280443945353267/1225849404037009609/1234206158630289450

while (current) {
while (current->next && current->next->next && current->next->val == current->next->next->val) {
int target_val = current->next->val;
while (current->next->val == target_val) {
current->next = current->next->next;
if (!current->next) {
break;
}
}
}
current = current->next;
}
ListNode* result = dummy_head->next;
delete dummy_head;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

new したオブジェクトをきちんと delete している点、とても良いと思います。

return result;
}
};
26 changes: 26 additions & 0 deletions 82/step2_1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
new演算子を使用せず、deleteを不要にした。
nextを何度も書くのに違和感があったのでgroup_top変数にした。
チェック済みの最後尾を指すcurrentと、チェック中/同一数値の先頭を指すのgroup_topと役割を分けてわかりやすくした

*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode dummy_head = ListNode(0, head);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こちらのように new を使わないほうがシンプルで良いと思います。

ListNode* current = &dummy_head;

while (current) {
ListNode* group_top = current->next;
while (group_top && group_top->next && group_top->val == group_top->next->val) {
int group_val = group_top->val;
while (group_top && group_top->val == group_val) {
group_top = group_top->next;
}
current->next = group_top;
}
current = current->next;
}
return dummy_head.next;
}
};
30 changes: 30 additions & 0 deletions 82/step2_2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
メソッド切り出しで多少読みやすくしたが、根本的なロジックは変わっていない。
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode dummy_head = ListNode(0, head);
ListNode* current = &dummy_head;

while (current) {
ListNode* group_top = current->next;
while (group_top && group_top->next && group_top->val == group_top->next->val) {
group_top = NextGroupTop(group_top);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

なんか、実質三重になっていませんか? (これでも動きそうですが。)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

真ん中の while が if でもいいような気がしますかね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

確かに3重whileはくどい気がしますね・・・

}
current->next = group_top;
current = current->next;
}
return dummy_head.next;
}

private:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

上記 public: 直下には空白がないので、合わせてこの空白も消した方が一貫性があって良いと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます、これは確かにそのとおりですね
一貫性の維持ができていませんでした。

ListNode* NextGroupTop(ListNode* head) {
ListNode* current = head;
while (current && current->next && current->val == current->next->val) {
current = current->next;
}
return current->next;
}
};
19 changes: 19 additions & 0 deletions 82/step3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode dummy_head = ListNode(-1, head);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

sentinelという名前で表現することもできます
https://www.geeksforgeeks.org/doubly-linked-list-using-sentinel-nodes/

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

なるほどありがとうございます。
sentinelはdummyよりも直感的ですね 🙏

ListNode* current = &dummy_head;
while (current) {
ListNode* group_top = current->next;
while (group_top && group_top->next && group_top->val == group_top->next->val) {
int group_val =group_top->val;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

= の両脇にスペースを 1 つづつ空けましょう。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます、typoでした 🙏

while (group_top && group_top->val == group_val) {
group_top = group_top->next;
}
}
current->next = group_top;
current = current->next;
}
Comment on lines +6 to +16
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

while 3重が気になりました
if 文を挟めば2重にできるかなと思います

Suggested change
while (current) {
ListNode* group_top = current->next;
while (group_top && group_top->next && group_top->val == group_top->next->val) {
int group_val =group_top->val;
while (group_top && group_top->val == group_val) {
group_top = group_top->next;
}
}
current->next = group_top;
current = current->next;
}
while (current) {
ListNode* group_top = current->next;
if (group_top && group_top->next && group_top->val == group_top->next->val) {
int group_val = group_top->val;
while (group_top && group_top->val == group_val) {
group_top = group_top->next;
}
current->next = group_top;
} else {
current = current->next;
}
}

Copy link
Copy Markdown
Owner Author

@colorbox colorbox Jul 12, 2024

Choose a reason for hiding this comment

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

コメントありがとうございます。
3重whieは確かに微妙ですね・・・ifで別途書き直してみます。

return dummy_head.next;
}
};
26 changes: 26 additions & 0 deletions 82/step4_with_if.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
レビュー指摘を受けて修正したコード
3重のwhileはそれで解けなくはないしパスするものの読みづらい
ifの代わりにwhileを使うと連続した同値グループをそのブロック内で処理できる利点があるが流石に3重whileは読みづらいのでダメ
ifを使用して、外側のループの中で処理する。
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode dummy_node = ListNode(-1, head);
ListNode* inspecting_node = &dummy_node;
while (inspecting_node) {
ListNode* group_top = inspecting_node->next;
if (group_top && group_top->next && group_top->val == group_top->next->val) {
int group_val = group_top->val;
while (group_top && group_top->val == group_val) {
inspecting_node->next = group_top->next;
group_top = group_top->next;
}
} else {
inspecting_node = inspecting_node->next;
}
}
return dummy_node.next;
}
};