【剑指Offer】复杂链表的复制
2018-01-26 11:18
573 查看
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)题目分析
如果是普通链表,那么将原链表遍历一遍,创建出新链表即可。但是这个链表中每个节点中有一个指向任意结点的指针,这就增加了实现的难度。对于这样的问题,有三种思路。1. 将原链表复制后,对于新链表中的每一个结点,在原链表中寻找其特殊指针指向的结点,然后在新链表中找到,并指向那个结点。时间复杂度为O(n^2)。
2. 将原链表的结点以及新链表的结点一一对应的存储在Hash表中,这样通过两次遍历链表的操作即可将链表复制。时间复杂度为O(n),空间复杂度为O(n)。
3. 将原链表的结点复制后,插入到原结点后面,这样复制完之后就会发现,新链表中每一个节点特殊指针即为原链表结点特殊指针后面的那个结点,这样的时间复杂度为O(n)。
代码实现
RandomListNode* RandomList::cloneByHashTable(RandomListNode* pHead){
if (pHead == NULL)
{
return NULL;
}
// 定义一个hash表 unordered_multimap<RandomListNode*, RandomListNode*> table; // 开辟一个头结点 RandomListNode* pCloneHead = new RandomListNode(0); pCloneHead->next = NULL; pCloneHead->random = NULL; //将头节 4000 点放入table中 table.insert(make_pair(pHead,pCloneHead)); // 设置操作指针 RandomListNode* pNode = pHead->next; RandomListNode*pCloneNode = pCloneHead; // 第一遍,先简单复制链表 while (pNode != NULL) { RandomListNode* pCloneTail = new RandomListNode(pNode->label); pCloneTail->next = pNode->next; pCloneTail->random = NULL; // 将复制的节点链接到复制链表的尾部 pCloneNode->next = pCloneTail; // 更新当前结点 pCloneNode = pCloneTail; // 将新的对应关系插入到Hash表 table.insert(make_pair(pNode,pCloneTail)); // 移动原链表操作指针 pNode = pNode->next; } // 需从头设置特殊指针,重新设置操作指针 pNode = pHead; pCloneNode = pCloneHead; while (pNode != NULL){ // 如果存在特殊指针,则设置之 if (pNode->random != NULL) { pCloneNode->random = table.find(pNode->random)->second; } // 移动原链表以及克隆链表 pNode = pNode->next; pCloneNode = pCloneNode->next; } return pCloneHead;
}
class RandomListNode { int label; RandomListNode next = null; RandomListNode random = null; RandomListNode(int label) { this.label = label; } } public class Solution { public RandomListNode Clone(RandomListNode pHead) { copyList(pHead); setSibling(pHead); return disconnectedList(pHead); } // 将复制后的结点放在原链表结点的尾部 private void copyList(RandomListNode head){ if(head == null) return; RandomListNode node = head; while(node != null){ RandomListNode copyNode = new RandomListNode(node.label); copyNode.next = node.next; copyNode.random = null; node.next = copyNode; node = copyNode.next; } } // 将链表中复制后的结点的random属性设置好 private void setSibling(RandomListNode head){ if(head == null) return; RandomListNode node = head; while(node != null){ RandomListNode copyNode = node.next; if(node.random != null){ copyNode.random = node.random.next; } node = copyNode.next; } } private RandomListNode disconnectedList(RandomListNode head){ RandomListNode node = head; RandomListNode copyHead = null; RandomListNode copyNode = null; if(node != null){ copyHead = node.next; copyNode = node.next; node.next = copyNode.next; node = node.next; } while(node != null){ copyNode.next = node.next; copyNode = copyNode.next; node.next = copyNode.next; node = node.next; } return copyHead; } }
相关文章推荐
- 剑指Offer学习总结-复杂链表的复制
- [剑指offer][面试题26]复杂链表的复制
- 剑指offer——面试题26:复杂链表的复制
- 【剑指Offer面试题】 九度OJ1524:复杂链表的复制
- 剑指offer:复杂链表的复制
- 剑指offer面试题26:复杂链表的复制
- 剑指 offer代码解析——面试题26复杂链表的复制
- 剑指offer: 复杂链表的复制
- 剑指offer:复杂链表的复制
- 【剑指offer】4.4分解让复杂问题简单化——面试题26:复杂链表的复制
- 剑指offer-面试题26 复杂链表的复制
- 剑指offer-4-面试26:复杂链表的复制
- 剑指offer 26 复杂链表的复制
- 剑指offer 复杂链表的复制
- 剑指Offer----面试题26:复杂链表的复制
- 剑指offer 面试题26复杂链表的复制
- 剑指Offer-复制复杂链表
- 剑指Offer24 复杂链表的复制
- 剑指offer--复杂链表的复制
- 剑指Offer - 九度1524 - 复杂链表的复制