From 504f06e7a76d68d57a2d8a6a1aba30024723c3ab Mon Sep 17 00:00:00 2001 From: maeken4 Date: Sun, 18 May 2025 21:33:57 +0900 Subject: [PATCH 1/3] step2 --- .../memo.md | 25 +++++++++++++++ .../step1.cpp | 30 +++++++++++++++++ .../step2.cpp | 32 +++++++++++++++++++ .../step2_another.cpp | 26 +++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 83.-Remove-Duplicates-from-Sorted-List/memo.md create mode 100644 83.-Remove-Duplicates-from-Sorted-List/step1.cpp create mode 100644 83.-Remove-Duplicates-from-Sorted-List/step2.cpp create mode 100644 83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp diff --git a/83.-Remove-Duplicates-from-Sorted-List/memo.md b/83.-Remove-Duplicates-from-Sorted-List/memo.md new file mode 100644 index 0000000..5bcae1f --- /dev/null +++ b/83.-Remove-Duplicates-from-Sorted-List/memo.md @@ -0,0 +1,25 @@ +# step1 +考えたこと +- setで通った値を管理して重複していたら組み換える。でもaccendingだったら切り替わりだけ見れば十分か。組み替えると破壊的なのでちょっと微妙 +- 新しく単方向リストを作る。入力を順にたどって切り替わりでリストを伸ばす。 +- ポインタに慣れておらず、newをつけておらず合わない。 + + +# step2 +- アルゴリズムは本質的に同じだけど、新井さんの解答をリストに対して破壊的なのでどっちがよいかは状況によりそう。面接なら確認しながら確認する。 +- 変数名がnow, ans, ansNowがわかりにくいのでchatpgtに代替案を考えてもらった。それぞれcurrentNode, resultHead, resultTailを採用。 + +| 役割 | 変数名候補(20個) | +|----------------|------------------------------------------------------------------------------------| +| **now** | current, currNode, traverse, cursor, walker, scan, nodePtr, reader, iterator, scanPtr, listWalker, inputCursor, explorer, readHead, probe, listPtr, sourcePtr, originWalker, traversePtr, scanNode | +| **ans** | resultHead, outputHead, newListHead, headOfResult, dedupedHead, uniqueListHead, resultList, filteredHead, cleanedListHead, distinctHead, newHead, answerHead, finalList, resultStart, startNode, processedHead, rootNode, firstNode, topOfResult, primaryNode | +| **ansNow** | resultTail, lastNode, resPtr, builder, insertPos, resultCursor, tail, constructPtr, appendNode, writer, resBuilder, outPtr, resultWalker, resultCurrent, collector, newTail, sinkPtr, outputTail, outCursor, resultIterator | + +- whileとifが入り乱れてデバッグに時間がかかってしまった。次のように整理した. +今見ているノード(!= nullptr)を基準に次の3パターンがある。 +1. 次がnullptr +2. 次のノードが今見ているノードと値が異なる。 +3. 次のノードが今見ているノードと値が等しい。 + + +1,2のときは見るノードを次に進めればよく、3のときだけ次のノードを組み替える。組み替えた先のノードが妥当かは次のループで見る。 diff --git a/83.-Remove-Duplicates-from-Sorted-List/step1.cpp b/83.-Remove-Duplicates-from-Sorted-List/step1.cpp new file mode 100644 index 0000000..0ff5788 --- /dev/null +++ b/83.-Remove-Duplicates-from-Sorted-List/step1.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) { + if (head == nullptr) { + return nullptr; + } + ListNode* now = head; + ListNode* ans = new ListNode(head->val); + ListNode* ansNow = ans; + while (now != nullptr && now->next != nullptr) { + if (now->val != now->next->val) { + ListNode* append = new ListNode(now->next->val); + ansNow->next = append; + ansNow = ansNow->next; + } + now = now->next; + } + return ans; + } +}; diff --git a/83.-Remove-Duplicates-from-Sorted-List/step2.cpp b/83.-Remove-Duplicates-from-Sorted-List/step2.cpp new file mode 100644 index 0000000..bce4e28 --- /dev/null +++ b/83.-Remove-Duplicates-from-Sorted-List/step2.cpp @@ -0,0 +1,32 @@ +// 戻り値用に新しくリストを作る解答 + +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 { + ListNode* deleteDuplicates(ListNode* head) { + if (head == nullptr) { + return nullptr; + } + ListNode* currentNode = head; + ListNode* resultHead = new ListNode(head->val); + ListNode* resultTail = resultHead; + while (currentNode != nullptr && currentNode->next != nullptr) { + if (currentNode->next != nullptr && + currentNode->val == currentNode->next->val) { + currentNode->next = currentNode->next->next; + } else { + ListNode* append = new ListNode(currentNode->next->val); + currentNode = currentNode->next; + resultTail->next = append; + resultTail = resultTail->next; + } + } + return resultHead; + } +}; diff --git a/83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp b/83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp new file mode 100644 index 0000000..193290a --- /dev/null +++ b/83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp @@ -0,0 +1,26 @@ +// 入力のリストを直接改変する方法 + +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 Soltion { + public: + ListNode* deleteDuplicates(ListNode* head) { + ListNode* currentNode = head; + while (currentNode != nullptr) { + // 次のノードの値が条件を満たさない場合、その次のノードにつなげる。 + if (currentNode->next != nullptr && + currentNode->val != currentNode->next->val) { + currentNode->next = currentNode->next->next; + } else { + currentNode = currentNode->next; + } + } + return head; + } +}; From 67e07c8fd8e09d3a2d098c1a6f8f1e634c2ac554 Mon Sep 17 00:00:00 2001 From: maeken4 Date: Fri, 23 May 2025 23:27:21 +0900 Subject: [PATCH 2/3] step3 --- .../step3.cpp | 23 ++++++++++++++++ .../step3_another.cpp | 26 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 83.-Remove-Duplicates-from-Sorted-List/step3.cpp create mode 100644 83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp diff --git a/83.-Remove-Duplicates-from-Sorted-List/step3.cpp b/83.-Remove-Duplicates-from-Sorted-List/step3.cpp new file mode 100644 index 0000000..231f719 --- /dev/null +++ b/83.-Remove-Duplicates-from-Sorted-List/step3.cpp @@ -0,0 +1,23 @@ +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* RemoveDuplicates(ListNode* head) { + ListNode* nowNode = head; + while (nowNode != nullptr) { + if (nowNode->next == nullptr || + nowNode->val != nowNode->next->val) { + nowNode = nowNode->next; + } else { + nowNode->next = nowNode->next->next; + } + } + return head; + } +}; diff --git a/83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp b/83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp new file mode 100644 index 0000000..add8279 --- /dev/null +++ b/83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp @@ -0,0 +1,26 @@ +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* nowNode = head; + ListNode* resultHead = nowNode ? new ListNode(nowNode->val) : nullptr; + ListNode* resultTail = resultHead; + while (nowNode) { + if (nowNode->next == nullptr) { + break; + } else if (nowNode->val != nowNode->next->val) { + ListNode* append = new ListNode(nowNode->next->val); + } + // 次のノードも同じ値の場合は何も追加せずに進む + nowNode = nowNode->next; + } + return resultHead; + } +}; From 0df0aa780424fc413db0f486d4aee3b3bc3e3c88 Mon Sep 17 00:00:00 2001 From: maeken4 Date: Sat, 24 May 2025 19:21:20 +0900 Subject: [PATCH 3/3] redo step3 --- .../step1.cpp | 44 ++++++++--------- .../step2.cpp | 49 +++++++++---------- .../step2_another.cpp | 35 +++++++------ .../step3.cpp | 37 +++++++------- .../step3_another.cpp | 44 +++++++++-------- 5 files changed, 107 insertions(+), 102 deletions(-) diff --git a/83.-Remove-Duplicates-from-Sorted-List/step1.cpp b/83.-Remove-Duplicates-from-Sorted-List/step1.cpp index 0ff5788..1faf8ed 100644 --- a/83.-Remove-Duplicates-from-Sorted-List/step1.cpp +++ b/83.-Remove-Duplicates-from-Sorted-List/step1.cpp @@ -1,30 +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) {} + 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) { - if (head == nullptr) { - return nullptr; - } - ListNode* now = head; - ListNode* ans = new ListNode(head->val); - ListNode* ansNow = ans; - while (now != nullptr && now->next != nullptr) { - if (now->val != now->next->val) { - ListNode* append = new ListNode(now->next->val); - ansNow->next = append; - ansNow = ansNow->next; - } - now = now->next; - } - return ans; - } + ListNode* deleteDuplicates(ListNode* head) { + if (head == nullptr) { + return nullptr; + } + ListNode* now = head; + ListNode* ans = new ListNode(head->val); + ListNode* ansNow = ans; + while (now != nullptr && now->next != nullptr) { + if (now->val != now->next->val) { + ListNode* append = new ListNode(now->next->val); + ansNow->next = append; + ansNow = ansNow->next; + } + now = now->next; + } + return ans; + } }; diff --git a/83.-Remove-Duplicates-from-Sorted-List/step2.cpp b/83.-Remove-Duplicates-from-Sorted-List/step2.cpp index bce4e28..7897cf3 100644 --- a/83.-Remove-Duplicates-from-Sorted-List/step2.cpp +++ b/83.-Remove-Duplicates-from-Sorted-List/step2.cpp @@ -1,32 +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) {} + 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 { - ListNode* deleteDuplicates(ListNode* head) { - if (head == nullptr) { - return nullptr; - } - ListNode* currentNode = head; - ListNode* resultHead = new ListNode(head->val); - ListNode* resultTail = resultHead; - while (currentNode != nullptr && currentNode->next != nullptr) { - if (currentNode->next != nullptr && - currentNode->val == currentNode->next->val) { - currentNode->next = currentNode->next->next; - } else { - ListNode* append = new ListNode(currentNode->next->val); - currentNode = currentNode->next; - resultTail->next = append; - resultTail = resultTail->next; - } - } - return resultHead; - } + ListNode* deleteDuplicates(ListNode* head) { + if (head == nullptr) { + return nullptr; + } + ListNode* currentNode = head; + ListNode* resultHead = new ListNode(head->val); + ListNode* resultTail = resultHead; + while (currentNode != nullptr && currentNode->next != nullptr) { + if (currentNode->next != nullptr && currentNode->val == currentNode->next->val) { + currentNode->next = currentNode->next->next; + } else { + ListNode* append = new ListNode(currentNode->next->val); + currentNode = currentNode->next; + resultTail->next = append; + resultTail = resultTail->next; + } + } + return resultHead; + } }; diff --git a/83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp b/83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp index 193290a..4b3b7c7 100644 --- a/83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp +++ b/83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp @@ -1,26 +1,25 @@ // 入力のリストを直接改変する方法 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) {} + 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 Soltion { public: - ListNode* deleteDuplicates(ListNode* head) { - ListNode* currentNode = head; - while (currentNode != nullptr) { - // 次のノードの値が条件を満たさない場合、その次のノードにつなげる。 - if (currentNode->next != nullptr && - currentNode->val != currentNode->next->val) { - currentNode->next = currentNode->next->next; - } else { - currentNode = currentNode->next; - } - } - return head; - } + ListNode* deleteDuplicates(ListNode* head) { + ListNode* currentNode = head; + while (currentNode != nullptr) { + // 次のノードの値が条件を満たさない場合、その次のノードにつなげる。 + if (currentNode->next != nullptr && currentNode->val != currentNode->next->val) { + currentNode->next = currentNode->next->next; + } else { + currentNode = currentNode->next; + } + } + return head; + } }; diff --git a/83.-Remove-Duplicates-from-Sorted-List/step3.cpp b/83.-Remove-Duplicates-from-Sorted-List/step3.cpp index 231f719..1c058f1 100644 --- a/83.-Remove-Duplicates-from-Sorted-List/step3.cpp +++ b/83.-Remove-Duplicates-from-Sorted-List/step3.cpp @@ -1,23 +1,26 @@ +// 入力のリストを改変する解法 + 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) {} + 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* RemoveDuplicates(ListNode* head) { - ListNode* nowNode = head; - while (nowNode != nullptr) { - if (nowNode->next == nullptr || - nowNode->val != nowNode->next->val) { - nowNode = nowNode->next; - } else { - nowNode->next = nowNode->next->next; - } - } - return head; - } + ListNode* deleteDuplicates(ListNode* head) { + ListNode* tail = head; + while (tail != nullptr) { + if (tail->next == nullptr || tail->val != tail->next->val) { + tail = tail->next; + } else { + ListNode* toDelete = tail->next; + tail->next = tail->next->next; + delete toDelete; + } + } + return head; + } }; diff --git a/83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp b/83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp index add8279..ca01ccb 100644 --- a/83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp +++ b/83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp @@ -1,26 +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) {} + 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* nowNode = head; - ListNode* resultHead = nowNode ? new ListNode(nowNode->val) : nullptr; - ListNode* resultTail = resultHead; - while (nowNode) { - if (nowNode->next == nullptr) { - break; - } else if (nowNode->val != nowNode->next->val) { - ListNode* append = new ListNode(nowNode->next->val); - } - // 次のノードも同じ値の場合は何も追加せずに進む - nowNode = nowNode->next; - } - return resultHead; - } + // 入力のリストも戻り値のリストもメモリ管理は呼び出し元で行う必要がある。 + ListNode* deleteDuplicates(ListNode* head) { + ListNode* nowNode = head; + ListNode* resultHead = nowNode ? new ListNode(nowNode->val) : nullptr; + ListNode* resultTail = resultHead; + while (nowNode != nullptr) { + if (nowNode->next == nullptr) { + break; + // 次のノードの値が異なる値であれば戻り値のリストに追加する + } else if (nowNode->val != nowNode->next->val) { + ListNode* appendNode = new ListNode(nowNode->next->val); + resultTail->next = appendNode; + resultTail = resultTail->next; + } + // 次のノードも同じ値の場合は何も追加せずに進んでよい + nowNode = nowNode->next; + } + return resultHead; + } };