复杂链表的复制
题目链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
思路:比较直接的想法是按序遍历原链表,用hashmap与新链表的每个节点建立一一对应的关系,然后再遍历新链表并根据对应关系补充random指针。
- 注意在下面的代码中并未特别处理random = NULL的情形,原因是在C++的unordered_map中,如果对不存在的key调用了[]运算符,会直接在原map中insert该key,并用默认构造函数构造其value;故调用m[NULL]将会把它的值赋为NULL,恰好符合要求
- 从代码健壮性和可读性上来说应该显式处理该情况
上面的思路需要用O(N)的额外空间,看题解有一种巧妙的不使用额外空间的解法:先将原链表与新链表交错拼接,然后构建新链表节点的random节点,再将两个链表拆分:class Solution {public:Node* copyRandomList(Node* head) {if (!head) {return NULL;}unordered_map<Node*, Node*> m;Node* curr = head;while (curr) {m[curr] = new Node(curr->val);curr = curr->next;}curr = head;while (curr) {m[curr]->next = m[curr->next];m[curr]->random = m[curr->random];curr = curr->next;}return m[head];}};

参考代码:class Solution {public:Node* copyRandomList(Node* head) {if(head == nullptr) return nullptr;Node* cur = head;// 1. 复制各节点,并构建拼接链表while(cur != nullptr) {Node* tmp = new Node(cur->val);tmp->next = cur->next;cur->next = tmp;cur = tmp->next;}// 2. 构建各新节点的 random 指向cur = head;while(cur != nullptr) {if(cur->random != nullptr)cur->next->random = cur->random->next;cur = cur->next->next;}// 3. 拆分两链表cur = head->next;Node* pre = head, *res = head->next;while(cur->next != nullptr) {pre->next = pre->next->next;cur->next = cur->next->next;pre = pre->next;cur = cur->next;}pre->next = nullptr; // 单独处理原链表尾节点return res; // 返回新链表头节点}
- 从代码健壮性和可读性上来说应该显式处理该情况
