Skip to content
Open
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
25 changes: 25 additions & 0 deletions 83.-Remove-Duplicates-from-Sorted-List/memo.md
Original file line number Diff line number Diff line change
@@ -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のときだけ次のノードを組み替える。組み替えた先のノードが妥当かは次のループで見る。
30 changes: 30 additions & 0 deletions 83.-Remove-Duplicates-from-Sorted-List/step1.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
};
31 changes: 31 additions & 0 deletions 83.-Remove-Duplicates-from-Sorted-List/step2.cpp
Original file line number Diff line number Diff line change
@@ -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 {
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;
}
};
25 changes: 25 additions & 0 deletions 83.-Remove-Duplicates-from-Sorted-List/step2_another.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +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) {}
};

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;
}
};
26 changes: 26 additions & 0 deletions 83.-Remove-Duplicates-from-Sorted-List/step3.cpp
Original file line number Diff line number Diff line change
@@ -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* 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;
}
};
30 changes: 30 additions & 0 deletions 83.-Remove-Duplicates-from-Sorted-List/step3_another.cpp
Original file line number Diff line number Diff line change
@@ -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* 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;
}
};