diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/a.out b/82.-Remove-Duplicates-from-Sorted-List-II/a.out new file mode 100755 index 0000000..b64fa3d Binary files /dev/null and b/82.-Remove-Duplicates-from-Sorted-List-II/a.out differ diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/memo.md b/82.-Remove-Duplicates-from-Sorted-List-II/memo.md new file mode 100644 index 0000000..0ad1584 --- /dev/null +++ b/82.-Remove-Duplicates-from-Sorted-List-II/memo.md @@ -0,0 +1,21 @@ +# step1 +83と同様に、確定しているノードの次のノードの状態で場合分けして考える + +tailまで確定しているとして(最初の場合分けも必要か?)、 +- tail.next == nullptr +- tail.next が採用できる=値が連続していない +- tail.next が採用できない=tail.nextから値が連続している + +が考えられる。番兵をおけば最初を場合分けなくて済む。 + +→ややこしくなってしまいとりあえず値のカウントリストを用意して解いた。 +# step2 +新井さんの解答ではやはり重複中を走るポインタをもう一つ用意していたのでそうすればすっきり実装できそう。 + +→discordを見て削除は値で行うことに変更。 + +小田さんの電車の振り分けの比喩で考えると、各日付の作業者は各日付のうちに重複を取り除くことにしtailを引き継ぎのない重複のない状態にして次の人に引き継ぐということ。 + + +# step3 +一重目のwhileで注目しているノードをcur_nodeで置いたけどあんまりわかりやすくなっていない? diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/step1.cpp b/82.-Remove-Duplicates-from-Sorted-List-II/step1.cpp new file mode 100644 index 0000000..2f9afd5 --- /dev/null +++ b/82.-Remove-Duplicates-from-Sorted-List-II/step1.cpp @@ -0,0 +1,32 @@ +#include +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + // 値の登場回数を管理する + std::map count; + for (ListNode* p = head; p != nullptr; p = p->next) { + count[p->val]++; + } + ListNode* dummy = new ListNode(0); + dummy->next = head; + ListNode* tail = dummy; + while (tail != nullptr && tail->next != nullptr) { + if (count[tail->next->val] > 1) { + tail->next = tail->next->next; + } else { + tail = tail->next; + } + } + ListNode* ans = dummy->next; + delete dummy; + return ans; + } +}; diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/step2.cpp b/82.-Remove-Duplicates-from-Sorted-List-II/step2.cpp new file mode 100644 index 0000000..e8fd160 --- /dev/null +++ b/82.-Remove-Duplicates-from-Sorted-List-II/step2.cpp @@ -0,0 +1,31 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + // スタック上に動的確保することで開放しなくてよくなる + ListNode dummy(0, head); + ListNode* tail = &dummy; + // tailまでは重複がないとして次のノードから確認する + while (tail->next && tail->next->next) { + if (tail->next->val != tail->next->next->val) { + tail = tail->next; + } else { + // 重複を検知した場合、値が被っている間ノードを消していく + int val_to_remove = tail->next->val; + while (tail->next && tail->next->val == val_to_remove) { + ListNode* toDelete = tail->next; + tail->next = tail->next->next; + delete toDelete; + } + } + } + return dummy.next; + } +}; diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/step3.cpp b/82.-Remove-Duplicates-from-Sorted-List-II/step3.cpp new file mode 100644 index 0000000..ef257c9 --- /dev/null +++ b/82.-Remove-Duplicates-from-Sorted-List-II/step3.cpp @@ -0,0 +1,30 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + ListNode dummy(0, head); + ListNode* tail = &dummy; + while (tail->next && tail->next->next) { + ListNode* cur_node = tail->next; + if (cur_node->val != cur_node->next->val) { + tail = cur_node; + continue; + } + int val_to_remove = cur_node->val; + while (cur_node && cur_node->val == val_to_remove) { + ListNode* to_delete = cur_node; + cur_node = cur_node->next; + delete to_delete; + } + tail->next = cur_node; + } + return dummy.next; + } +}; diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/step3_2.cpp b/82.-Remove-Duplicates-from-Sorted-List-II/step3_2.cpp new file mode 100644 index 0000000..fdc8aa1 --- /dev/null +++ b/82.-Remove-Duplicates-from-Sorted-List-II/step3_2.cpp @@ -0,0 +1,31 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + ListNode dummy(-1, head); + ListNode* last_non_duplicate_node = &dummy; + ListNode* cur_node = last_non_duplicate_node->next; + while (cur_node && cur_node->next) { + if (cur_node->val != cur_node->next->val) { + last_non_duplicate_node = cur_node; + cur_node = cur_node->next; + continue; + } + int val_to_remove = cur_node->val; + while (cur_node && cur_node->val == val_to_remove) { + ListNode* to_delete = cur_node; + cur_node = cur_node->next; + delete to_delete; + } + last_non_duplicate_node->next = cur_node; + } + return dummy.next; + } +}; diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/step4.cpp b/82.-Remove-Duplicates-from-Sorted-List-II/step4.cpp new file mode 100644 index 0000000..d4cf4ca --- /dev/null +++ b/82.-Remove-Duplicates-from-Sorted-List-II/step4.cpp @@ -0,0 +1,30 @@ +#include + +struct ListNode { + int val; + std::unique_ptr next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, std::unique_ptr next) : val(x), next(std::move(next)) {} +}; + +class Solution { + public: + std::unique_ptr removeDuplicate(std::unique_ptr head) { + std::unique_ptr dummy = std::make_unique(0); + dummy->next = std::move(head); + std::unique_ptr* tail = &dummy->next; + + while (*tail && (*tail)->next) { + if ((*tail)->val != (*tail)->next->val) { + tail = &(*tail)->next; + } else { + int val_to_remove = (*tail)->val; + while (*tail && (*tail)->val == val_to_remove) { + *tail = std::move((*tail)->next); // 外れたノードは自動で delete + } + } + } + return std::move(dummy->next); + } +}; diff --git a/82.-Remove-Duplicates-from-Sorted-List-II/test.cpp b/82.-Remove-Duplicates-from-Sorted-List-II/test.cpp new file mode 100644 index 0000000..3d295e8 --- /dev/null +++ b/82.-Remove-Duplicates-from-Sorted-List-II/test.cpp @@ -0,0 +1,15 @@ +// ポインタと参照の違い + +#include +void func(int& x) { + x += 10; + printf("%p\n", &x); +} +int main() { + int b = 10; + int& c = b; + std::cout << c << std::endl; // 10 + printf("%p\n", &b); + func(b); // bは20になる + std::cout << b << std::endl; +} diff --git a/84.-Remove-Duplicates-from-Sorted-List-II/memo.md b/84.-Remove-Duplicates-from-Sorted-List-II/memo.md new file mode 100644 index 0000000..0ad1584 --- /dev/null +++ b/84.-Remove-Duplicates-from-Sorted-List-II/memo.md @@ -0,0 +1,21 @@ +# step1 +83と同様に、確定しているノードの次のノードの状態で場合分けして考える + +tailまで確定しているとして(最初の場合分けも必要か?)、 +- tail.next == nullptr +- tail.next が採用できる=値が連続していない +- tail.next が採用できない=tail.nextから値が連続している + +が考えられる。番兵をおけば最初を場合分けなくて済む。 + +→ややこしくなってしまいとりあえず値のカウントリストを用意して解いた。 +# step2 +新井さんの解答ではやはり重複中を走るポインタをもう一つ用意していたのでそうすればすっきり実装できそう。 + +→discordを見て削除は値で行うことに変更。 + +小田さんの電車の振り分けの比喩で考えると、各日付の作業者は各日付のうちに重複を取り除くことにしtailを引き継ぎのない重複のない状態にして次の人に引き継ぐということ。 + + +# step3 +一重目のwhileで注目しているノードをcur_nodeで置いたけどあんまりわかりやすくなっていない? diff --git a/84.-Remove-Duplicates-from-Sorted-List-II/step1.cpp b/84.-Remove-Duplicates-from-Sorted-List-II/step1.cpp new file mode 100644 index 0000000..2f9afd5 --- /dev/null +++ b/84.-Remove-Duplicates-from-Sorted-List-II/step1.cpp @@ -0,0 +1,32 @@ +#include +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + // 値の登場回数を管理する + std::map count; + for (ListNode* p = head; p != nullptr; p = p->next) { + count[p->val]++; + } + ListNode* dummy = new ListNode(0); + dummy->next = head; + ListNode* tail = dummy; + while (tail != nullptr && tail->next != nullptr) { + if (count[tail->next->val] > 1) { + tail->next = tail->next->next; + } else { + tail = tail->next; + } + } + ListNode* ans = dummy->next; + delete dummy; + return ans; + } +}; diff --git a/84.-Remove-Duplicates-from-Sorted-List-II/step2.cpp b/84.-Remove-Duplicates-from-Sorted-List-II/step2.cpp new file mode 100644 index 0000000..e8fd160 --- /dev/null +++ b/84.-Remove-Duplicates-from-Sorted-List-II/step2.cpp @@ -0,0 +1,31 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + // スタック上に動的確保することで開放しなくてよくなる + ListNode dummy(0, head); + ListNode* tail = &dummy; + // tailまでは重複がないとして次のノードから確認する + while (tail->next && tail->next->next) { + if (tail->next->val != tail->next->next->val) { + tail = tail->next; + } else { + // 重複を検知した場合、値が被っている間ノードを消していく + int val_to_remove = tail->next->val; + while (tail->next && tail->next->val == val_to_remove) { + ListNode* toDelete = tail->next; + tail->next = tail->next->next; + delete toDelete; + } + } + } + return dummy.next; + } +}; diff --git a/84.-Remove-Duplicates-from-Sorted-List-II/step3.cpp b/84.-Remove-Duplicates-from-Sorted-List-II/step3.cpp new file mode 100644 index 0000000..ef257c9 --- /dev/null +++ b/84.-Remove-Duplicates-from-Sorted-List-II/step3.cpp @@ -0,0 +1,30 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + ListNode dummy(0, head); + ListNode* tail = &dummy; + while (tail->next && tail->next->next) { + ListNode* cur_node = tail->next; + if (cur_node->val != cur_node->next->val) { + tail = cur_node; + continue; + } + int val_to_remove = cur_node->val; + while (cur_node && cur_node->val == val_to_remove) { + ListNode* to_delete = cur_node; + cur_node = cur_node->next; + delete to_delete; + } + tail->next = cur_node; + } + return dummy.next; + } +}; diff --git a/84.-Remove-Duplicates-from-Sorted-List-II/step3_2.cpp b/84.-Remove-Duplicates-from-Sorted-List-II/step3_2.cpp new file mode 100644 index 0000000..fdc8aa1 --- /dev/null +++ b/84.-Remove-Duplicates-from-Sorted-List-II/step3_2.cpp @@ -0,0 +1,31 @@ +struct ListNode { + int val; + ListNode* next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode* next) : val(x), next(next) {} +}; + +class Solution { + public: + ListNode* deleteDuplicates(ListNode* head) { + ListNode dummy(-1, head); + ListNode* last_non_duplicate_node = &dummy; + ListNode* cur_node = last_non_duplicate_node->next; + while (cur_node && cur_node->next) { + if (cur_node->val != cur_node->next->val) { + last_non_duplicate_node = cur_node; + cur_node = cur_node->next; + continue; + } + int val_to_remove = cur_node->val; + while (cur_node && cur_node->val == val_to_remove) { + ListNode* to_delete = cur_node; + cur_node = cur_node->next; + delete to_delete; + } + last_non_duplicate_node->next = cur_node; + } + return dummy.next; + } +}; diff --git a/84.-Remove-Duplicates-from-Sorted-List-II/test.cpp b/84.-Remove-Duplicates-from-Sorted-List-II/test.cpp new file mode 100644 index 0000000..3d295e8 --- /dev/null +++ b/84.-Remove-Duplicates-from-Sorted-List-II/test.cpp @@ -0,0 +1,15 @@ +// ポインタと参照の違い + +#include +void func(int& x) { + x += 10; + printf("%p\n", &x); +} +int main() { + int b = 10; + int& c = b; + std::cout << c << std::endl; // 10 + printf("%p\n", &b); + func(b); // bは20になる + std::cout << b << std::endl; +}