剑指offer:复杂链表的复制
2016-12-09 18:12
423 查看
题目:请实现函数complexListNode*Clone(ComplexListNode*pHead),
复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL.
复杂链表如图例:
我们对单链表的复制已经很清楚,因此很容易形成思路,先将链表整个复制,但是先将m_pSiling初始化为NULL(显然,我们在所有节点不全存在的时候是不能进行m_pSiling的设置的,因为它很有可能指向的结点现在并没有创建);有了第一步所有结点都存在时,我们可以根据原链表中当前结点和其m_pSiling指向结点的位置关系来设置该指针。
//第一步:实现next复制,使整个链表成型
//第二步:对每个结点,通过在源结点查找到random指针指向的是距离头结点第几个结点,
//那么复制的链表对应的结点的random也指向距头结点第几个结点
//复杂度是O(n)+o(n)*n
当然有更好的思路(来源于剑指offer)
//更好的思路是(特点:思路巧妙,相对复杂,实现也相对麻烦,复杂度低)
//第一步:复制(将A
//复杂度:O(n)+O(1)*n+O(n)
(1)将复制链表每一个结点依附于源结点(极大的便利了m_pSiling的设置)
(2)设置m_pSiling
(3)拆分原链表和复制链表
其实大多数人一旦知道这种依附于源结点创建复制结点的想法后,其他的思路都会自然而来的,只是指针操作看似简单,还是要十分小心,考虑周到。
附代码:
结点的结构体:
指针的题真的要思考清楚了再动笔,另外循环中语句的先后顺序与循环条件的设置是有关系的,琢磨琢磨就会形成自己的一套不易出错的模式。
欢迎交流指导~
复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL.
复杂链表如图例:
我们对单链表的复制已经很清楚,因此很容易形成思路,先将链表整个复制,但是先将m_pSiling初始化为NULL(显然,我们在所有节点不全存在的时候是不能进行m_pSiling的设置的,因为它很有可能指向的结点现在并没有创建);有了第一步所有结点都存在时,我们可以根据原链表中当前结点和其m_pSiling指向结点的位置关系来设置该指针。
//第一步:实现next复制,使整个链表成型
//第二步:对每个结点,通过在源结点查找到random指针指向的是距离头结点第几个结点,
//那么复制的链表对应的结点的random也指向距头结点第几个结点
//复杂度是O(n)+o(n)*n
当然有更好的思路(来源于剑指offer)
//更好的思路是(特点:思路巧妙,相对复杂,实现也相对麻烦,复杂度低)
//第一步:复制(将A
复制在A的后面) //第二步:设置random //第三步:将A和A分开
//复杂度:O(n)+O(1)*n+O(n)
(1)将复制链表每一个结点依附于源结点(极大的便利了m_pSiling的设置)
(2)设置m_pSiling
(3)拆分原链表和复制链表
其实大多数人一旦知道这种依附于源结点创建复制结点的想法后,其他的思路都会自然而来的,只是指针操作看似简单,还是要十分小心,考虑周到。
附代码:
class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { RandomListNode* mergeHead = copyAfter(pHead); buildRandom(mergeHead); RandomListNode*newHead = splitList(mergeHead); return newHead; } private: RandomListNode*copyAfter(RandomListNode*pHead){ //RandomListNode* pCopyHead = NULL; if (pHead == NULL) return NULL; RandomListNode*p1 = pHead; RandomListNode*p2; //pCopyHead = p2; ///p2->next = p1->next; //p1->next = p2; //p1 = p2->next; while (p1){ p2 = new RandomListNode(p1->label); p2->next = p1->next; p1->next = p2; p1 = p2->next; } return pHead; } void buildRandom(RandomListNode* mergeHead){ if (mergeHead == NULL) return; RandomListNode*p1 = mergeHead; RandomListNode*p2; RandomListNode*pRandom; while (p1){ p2 = p1->next; pRandom = p1->random; if (pRandom)//有空的情况 p2->random = pRandom->next; p1 = p2->next; } } RandomListNode* splitList(RandomListNode* mergeHead){ if (mergeHead == NULL) return NULL; RandomListNode*newHead; RandomListNode*p2 = newHead = mergeHead->next; RandomListNode*p1 = mergeHead; p1->next = p2->next; p1 = p1->next; while (p1){ p2->next = p1->next; p2 = p2->next; p1->next = p2->next; p1 = p1->next; } return newHead; } };
结点的结构体:
struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } };
指针的题真的要思考清楚了再动笔,另外循环中语句的先后顺序与循环条件的设置是有关系的,琢磨琢磨就会形成自己的一套不易出错的模式。
欢迎交流指导~
相关文章推荐
- 剑指offer题解 复杂链表的复制
- 剑指offer之面试题26 复杂链表的复制 之 链表插入删除结点不断链不覆盖
- 【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
- 【剑指offer】4.4分解让复杂问题简单化——面试题26:复杂链表的复制
- 剑指offer-面试题26-复杂链表的复制
- 剑指offer复杂链表复制
- 剑指offer——35复杂链表的复制
- 剑指offer--复杂链表的复制
- 剑指offer-复杂链表的复制
- 剑指offer—复杂链表的复制
- 剑指Offer 26 复杂链表的复制
- 【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
- 剑指Offer面试题:24.复杂链表的复制
- 剑指offer 复杂链表的复制
- 剑指offer面试题26-复杂链表的复制
- 剑指offer-25.复杂链表的复制
- 【剑指Offer】复杂链表的复制
- 剑指Offer - 九度1524 - 复杂链表的复制
- 剑指offer 面试题26复杂链表的复制
- 剑指offer-第四章解决面试题思路(复杂链表的复制)