【链表】复杂链表的复制
题目:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解答:
3 4 /* 5 *解题思路: 6 *1、遍历链表,复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面; 7 *2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next; 8 *3、拆分链表,将链表拆分为原链表和复制后的链表 9 */ 10 public class Solution { 11 public RandomListNode Clone(RandomListNode pHead) { 12 if(pHead == null) { 13 return null; 14 } 15 16 RandomListNode currentNode = pHead; 17 //1、复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面; 18 while(currentNode != null){ 19 RandomListNode cloneNode = new RandomListNode(currentNode.label); 20 RandomListNode nextNode = currentNode.next; 21 currentNode.next = cloneNode; 22 cloneNode.next = nextNode; 23 currentNode = nextNode; 24 } 25 26 currentNode = pHead; 27 //2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next; 28 while(currentNode != null) { 29 currentNode.next.random = currentNode.random==null?null:currentNode.random.next; 30 currentNode = currentNode.next.next; 31 } 32 33 //3、拆分链表,将链表拆分为原链表和复制后的链表 34 currentNode = pHead; 35 RandomListNode pCloneHead = pHead.next; 36 while(currentNode != null) { 37 RandomListNode cloneNode = currentNode.next; 38 currentNode.next = cloneNode.next; 39 cloneNode.next = cloneNode.next==null?null:cloneNode.next.next; 40 currentNode = currentNode.next; 41 } 42 43 return pCloneHead; 44 } 45 }
C++版本:
/* // Definition for a Node. class Node { public: int val; Node* next; Node* random; Node(int _val) { val = _val; next = NULL; random = NULL; } }; */ class Solution { public: Node* copyRandomList(Node* head) { // 注意 if (NULL == head) { return head; } // 1. 在旧链表中创建新链表, 此时不处理新链表的兄弟结点 Node *curr = head; while (curr != NULL) { // Node *clonenode = new Node(curr->val); // Node *nextnode = curr->next; // curr->next = clonenode; // clonenode->next = nextnode; // curr = nextnode; Node * clonenode = new Node(curr->val); clonenode->next = curr->next; curr->next = clonenode; curr = clonenode->next; } // 2. 根据旧链表的兄弟结点, 初始化新链表的兄弟结点 // 重新遍历链表, 复制老结点的随机指针给新结点 curr = head; while (curr != NULL) { // curr->random == NULL 时, 不能直接赋值为curr->random->next,所以需要判断下 curr->next->random = (curr->random == NULL ? NULL : curr->random->next); curr = curr->next->next; } // 3. 拆分链表, 将链表拆分为源链表和复制后的链表 curr = head; Node *clonehead = head->next; while (curr != NULL) { Node *clonenode = curr->next; curr->next = clonenode->next; curr = curr->next; // clonenode->next = (clonenode->next == NULL ? NULL : clonenode->next->next); clonenode->next = (curr == NULL ? NULL : curr->next); } return clonehead; } };