diff --git a/82/step1.cpp b/82/step1.cpp new file mode 100644 index 0000000..495957a --- /dev/null +++ b/82/step1.cpp @@ -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; + 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; + return result; + } +}; diff --git a/82/step2_1.cpp b/82/step2_1.cpp new file mode 100644 index 0000000..ff8f4b9 --- /dev/null +++ b/82/step2_1.cpp @@ -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); + 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; + } +}; diff --git a/82/step2_2.cpp b/82/step2_2.cpp new file mode 100644 index 0000000..ca7c02c --- /dev/null +++ b/82/step2_2.cpp @@ -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); + } + current->next = group_top; + current = current->next; + } + return dummy_head.next; + } + +private: + + ListNode* NextGroupTop(ListNode* head) { + ListNode* current = head; + while (current && current->next && current->val == current->next->val) { + current = current->next; + } + return current->next; + } +}; diff --git a/82/step3.cpp b/82/step3.cpp new file mode 100644 index 0000000..68ab75d --- /dev/null +++ b/82/step3.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + ListNode* deleteDuplicates(ListNode* head) { + ListNode dummy_head = ListNode(-1, 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) { + 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; + } +}; diff --git a/82/step4_with_if.cpp b/82/step4_with_if.cpp new file mode 100644 index 0000000..b067795 --- /dev/null +++ b/82/step4_with_if.cpp @@ -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; + } +};