二刷:好几次才过:
1.label写成val
2.最后一个函数赋值逻辑错误
3.random可能是nullptr,所以不能直接->random->next
4.同一刷的第二。最后只有一个nullptr,需要手动赋一个nullptr。
些许欣慰的是,一刷里的while-do do-while问题这次写的应该比较合理。
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
DoubleList(pHead);
HandleRandom(pHead);
return SplitList(pHead);
}
void DoubleList(RandomListNode* pHead) {
RandomListNode* pNode = pHead;
while(pNode != nullptr) {
RandomListNode* pNew = new RandomListNode(pNode->label);
pNew->next = pNode->next;
pNode->next = pNew;
pNode = pNew->next;
}
}
void HandleRandom(RandomListNode* pHead) {
RandomListNode* pNode = pHead;
RandomListNode* pClone;
while(pNode != nullptr) {
pClone = pNode->next;
if(pNode->random != nullptr) {
pClone->random = pNode->random->next;
}
pNode = pClone->next;
}
}
RandomListNode* SplitList(RandomListNode* pHead) {
if(pHead == nullptr) return nullptr;
RandomListNode* pNewHead = pHead->next;
RandomListNode* pNode = pHead;
RandomListNode* pClone;
while(pNode != nullptr) {
pClone = pNode->next;
pNode->next = pClone->next;
pClone->next = pNode->next == nullptr ? nullptr : pNode->next->next;
pNode = pNode->next;
}
return pNewHead;
}
};
/****************************************************/
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if(pHead == nullptr) return nullptr;
CloneNodes(pHead);
HadleRandom(pHead);
return ReConnect(pHead);
}
void CloneNodes(RandomListNode* pHead) {
RandomListNode* pNode = pHead;
do {
RandomListNode* pNew = new RandomListNode(pNode->label);
pNew->next = pNode->next;
pNode->next = pNew;
pNode = pNew->next;
} while(pNode != nullptr);
}
void HadleRandom(RandomListNode* pHead) {
RandomListNode* pNode = pHead;
do {
if(pNode->random != nullptr) {
pNode->next->random = pNode->random->next;
}
pNode = pNode->next->next;
} while(pNode != nullptr);
}
RandomListNode* ReConnect(RandomListNode* pHead) {
RandomListNode* pNode = pHead;
RandomListNode* pHeadCloned = pHead->next;
RandomListNode* pNodeCloned = pHeadCloned;
do {
pNode->next = pNodeCloned->next;
pNodeCloned->next = pNode->next == nullptr ? nullptr : pNode->next->next;
pNode = pNode->next;
pNodeCloned = pNodeCloned->next;
} while(pNode != nullptr);
return pHeadCloned;
}
};
题目不难,修修补补才通过。
第一次:while do后面没加分号、random写错。
第二次:边界值&指针访问前确定非空问题,拆分的时候因为尾部只有一个nullptr,取不到nullptr->next,需要多加谨慎。
第三次:hadleRandom里的pNode = pNode->next->next语句不小心放if里了,导致循环出不来。
另外我在主函数里先检测了一下头指针非空,在三个功能函数里用了do-while语句。这样可能不是很合适。书上用的while-do,相当于在每个子函数都检验了,这样应该更符合函数功能的独立性。