LeetCode: 138. Copy List with Random Pointer

题目描述

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.

解题思路

  1. 将原始链表的每一个节点复制作为其 next 节点(copyRandomListWithoutRandom)。
  2. 复制节点的 random 节点,即使原节点的 random 节点的 next 节点(copyRandomListRandom)。
  3. 生成复制链表,恢复原链表(copyRandomListGenerator)。
  4. 例子(1(3)==>2(1)==>3(nullptr)==>4(1)==>nullptr)
    a. 初始状态

    b. 复制链表(不包含 random),将复制节点作为原节点的 next 节点

    c. 复制链表的 random 属性
    处理一个节点:

    处理全部节点:

    d. 生成复制链表, 恢复原链表。
    处理一个节点:

    处理两个节点:

    处理三个节点:

    处理全部节点:

AC 代码

/** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; * RandomListNode *next, *random; * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} * }; */
class Solution 
{
private:
    // 拷贝 Random List(不包括 random 属性), 并将拷贝的内容插入原节点之后
    void copyRandomListWithoutRandom(RandomListNode *head)
    {
        if(head == nullptr) return ;

        auto iter = head;

        // 拷贝 head 节点
        RandomListNode * headCopy = new RandomListNode(head->label);
        // 将 headCopy 插入 head 后面
        headCopy->next = head->next;
        head->next = headCopy;

        // 处理后面的节点
        copyRandomListWithoutRandom(head->next->next);
    }

    // 拷贝 random 属性
    void copyRandomListRandom(RandomListNode *head)
    {
        if(head == nullptr) return;

        // NOTE: 原节点的 next 指针指向的是拷贝的节点
        if(head->random != nullptr)
        {
            head->next->random = head->random->next;
        }
        // 处理后面的节点
        copyRandomListRandom(head->next->next);
    }

    // 生成拷贝链表,恢复原链表
    RandomListNode* copyRandomListGenerator(RandomListNode *head)
    {
        if(head == nullptr) return nullptr;

        // NOTE: 原节点的 next 指针指向的是拷贝的节点
        RandomListNode* headCopy = head->next;
        head->next = headCopy->next;

        // 继续处理后面的节点
        headCopy->next = copyRandomListGenerator(head->next);

        return headCopy;
    }
public:
    RandomListNode *copyRandomList(RandomListNode *head) 
    {
        // 拷贝 Random List(不包括 random 属性), 并将拷贝的内容插入原节点之后
        copyRandomListWithoutRandom(head);

        // 拷贝 random 属性
        copyRandomListRandom(head);

        // 生成拷贝链表,恢复原链表
        return copyRandomListGenerator(head);
    }
};