剑指offer - 复杂链表的复制
2015-10-02 18:07
531 查看
题目:实现函数 ComplexListNode* Clone( ComplexListNode* pHead ), 复制一个复杂链表,在复杂链表中除了有一个 pNext 指针指向下一个结点外,还有一个 pSibling 指向链表中的任意结点或者NULL, 结点定义如下:
对于这个问题,有三种思路:
思路1:第一步先复制原始链表的每一个结点,并用 pNext 链接起来。第二步设置每个结点的 pSibling 指针。假设原始链表中某个结点N的pSibling指向结点S,由于S的位置在链表中的遍历时间复杂度为 O(n),这个对于一个含有n个结点的链表,该方法总的时间复杂度为 O(n^2);
思路2:在上面的算法中,由于时间复杂度主要花费在定位结点 pSibling 上,因此可以试着在这方面去做优化。我们还是分为两步,第一步复制原始链表上的每个结点N创建N‘, 然后把这些创建出来的结点用 pNext 连接起来,同时把 <N, N'> 的配对信息存在一个哈希表中。 第二步还是设置复制链表上每个结点的 pSibling。如果在原始链表中结点N的pSibling指向某个结点S, 那么在复制链表中对应的N’应该指向S。而有了哈希表,我们就可以在O(1)时间根据S找到S’了。此方法是利用了空间换取时间。通过一个大小为O(n)的哈希表,使得该算法的时间复杂度从O(n^2)变到
O(n);
★思路3:在不利用辅助空间的情况下,我们依旧复制原始链表的每个结点N来创建对应的N‘, 只是这次把N’ 链接在结点N的后面。完成这步的代码如下:
复制完结点后,接下来需要设置每个新结点的 pSibling。假设原始链表中结点N指向的pSibling为S, 那么对应的结点N‘ 指向的pSibling也为S’。故完成这步的代码如下所示:
完成上面两步后,现在的链表是有原始链表和复制链表组合而成的,因此现在可以通过奇偶位来得到复制的链表,实现代码如下:
struct ComplexListNode{ int value; ComplexListNode* pNext; ComplexListNode* pSibling; };
对于这个问题,有三种思路:
思路1:第一步先复制原始链表的每一个结点,并用 pNext 链接起来。第二步设置每个结点的 pSibling 指针。假设原始链表中某个结点N的pSibling指向结点S,由于S的位置在链表中的遍历时间复杂度为 O(n),这个对于一个含有n个结点的链表,该方法总的时间复杂度为 O(n^2);
思路2:在上面的算法中,由于时间复杂度主要花费在定位结点 pSibling 上,因此可以试着在这方面去做优化。我们还是分为两步,第一步复制原始链表上的每个结点N创建N‘, 然后把这些创建出来的结点用 pNext 连接起来,同时把 <N, N'> 的配对信息存在一个哈希表中。 第二步还是设置复制链表上每个结点的 pSibling。如果在原始链表中结点N的pSibling指向某个结点S, 那么在复制链表中对应的N’应该指向S。而有了哈希表,我们就可以在O(1)时间根据S找到S’了。此方法是利用了空间换取时间。通过一个大小为O(n)的哈希表,使得该算法的时间复杂度从O(n^2)变到
O(n);
★思路3:在不利用辅助空间的情况下,我们依旧复制原始链表的每个结点N来创建对应的N‘, 只是这次把N’ 链接在结点N的后面。完成这步的代码如下:
void CloneNodes( ComplexListNode * pHead ){ ComplexListNode *pNode = pHead; while( pNode != NULL){ ComplexListNode *pClone = new ConplexListNode(); pClone->value = pNode->value; pClone->pNext = pNode->pNext; pNode->pNext = pClone; pNode = pClone->pNext; } }
复制完结点后,接下来需要设置每个新结点的 pSibling。假设原始链表中结点N指向的pSibling为S, 那么对应的结点N‘ 指向的pSibling也为S’。故完成这步的代码如下所示:
void ConnectSiblingNodes( ComplexListNode *pHead ){ ComplexListNode *pNode = pHead; while( pNode != NULL ){ ComplextListNode *pClone = pNode->pNext; if( pNode->pSibling != NULL ){ pClone->pSibling = pNode->pSibling->mNext; } pNode = pClone->pNext; } }
完成上面两步后,现在的链表是有原始链表和复制链表组合而成的,因此现在可以通过奇偶位来得到复制的链表,实现代码如下:
ComplexListNode* ReconnectListNode( ComplexListNode* pHead ){ ComplexListNode *pNode = pHead; ComplexListNode *pCloneHead = NULL; ComplexListNode *pCloneNode = NULL; if( pNode != NULL ){ pCloneHead = pCloneNode = pNode->pNext; pNode = pCloneNode->pNext; while( pNode != NULL ){ pCloneNode->pNext = pNode->pNext; pCloneNode = pCloneNode->pNext; pNode = pCloneNode->pNext; } } return pCloneHead; }
相关文章推荐
- jQuery获取页面及个元素高度、宽度
- javascript把地址栏中的中文取出不含乱码的方法
- html 标签知识
- 2015-09-28 Javascript
- [LeetCode][JavaScript]Find the Duplicate Number
- BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元
- Html5+Css3实现简单表格排版
- js 验证表单 js提交验证类
- 高性能I/O设计模式Reactor和Proactor
- 使用dbms_file_transfer传输ASM file出现ORA-15001
- Node.js第三方模块之htmlparser2
- javaweb div+css布局
- 前端图片选择问题
- 【nodemailer】 之邮件附件
- 【 D3.js 入门系列 --- 0 】 简介及安装
- Jquery中Ajax的几种用法
- 淘宝前端工程师:国内WEB前端开发十日谈
- Node.js第三方库之request
- JAVA实现链表中倒数第K个节点问题(《剑指offer》)
- 03 crawler