《从头再来》剑指offer.35 复杂链表的复制
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
本题主要的难点就是random指针不好理解。
第一种方法:采用哈希表来解决。首先定义一个指针和一个哈希表,指针指向链表头部,然后遍历链表构建原链表节点和新链表对应节点的键值对关系,即创建一个和原链表一模一样的键值(new Node),然后再次遍历构建新链表各节点的next和random引用指向。最后返回哈希表的头节点即可。
/* // 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(head == nullptr) return nullptr; unordered_map<Node*, Node*> map; Node* cur = head; //建表 while(cur != nullptr){ map[cur] = new Node(cur->val);//因为是利用当前节点的值创建一个新的节点,所以一定要new Node(cur->val) cur = cur->next; } cur = head; while(cur != nullptr){ map[cur]->next = map[cur->next]; map[cur]->random = map[cur->random]; cur = cur->next; } cur = head; return map[cur]; } };
第二种方法:采用复制、拼接,构建指向关系,最后拆分的方案。
需要注意的时,复制节点的时候,要先使构建节点的next指向cur的next,再使cur的next指向构建的节点,移动cur指针时,cur应该直接指向copy的next。
/* // 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(head == nullptr) return nullptr; //1、复制+拼接 Node* cur = head; while(cur != nullptr){ //新建一个和cur一模一样的节点,并拼接 Node* copy = new Node(cur->val); copy->next = cur->next; cur->next = copy; //移动cur cur = copy->next; } //2、构建指向关系 cur = head;//位置指针回到开头 while(cur != nullptr){ if(cur->random != nullptr){ cur->next->random = cur->random->next; } //移动位置指针 cur = cur->next->next; } //3、拆分 //定义两个新节点,一个指向原链表的头节点,一个指向拆分后新链表的头节点 Node* old = head; Node* newList = head->next; cur = head->next; while(cur->next != nullptr){ old->next = old->next->next; cur->next = cur->next->next; //移动指针 old = old->next; cur = cur->next; } old->next = nullptr; return newList; } };
《从头再来》

浙公网安备 33010602011771号