在不限制时间复杂度的情况下,这题难度并不高。 首先遍历一次链表来深拷贝出一个新链表,这次深拷贝不考虑random的值,仅将链表的label和next深拷贝出来。这样就得到了链表的基本骨架。再用一个二重循环遍历链表,每次处理一个结点,通过一个循环来从骨架链表中找到一个label域和原链表中ramdom域的label域相等的结点,将该结点赋给被处理结点的random域。 这样做使用了一个二重循环,时间复杂度为O(n^2),空间复杂度为O(1)。

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    RandomListNode* Clone(RandomListNode* pHead) {
        if(!pHead){
            return nullptr;
        }
        RandomListNode* newHead = new RandomListNode(pHead->label);
        RandomListNode* p = pHead->next;
        RandomListNode* pre = newHead;
        while(p){
            pre->next = new RandomListNode(p->label);
            pre = pre->next;
            p = p->next;
        }
        p = pHead;
        pre = newHead;
        while(pre){
            if(p->random == nullptr){
                p = p->next;
                pre = pre->next;
                continue;
            }
            RandomListNode* temp = newHead;
            while(temp){
                if(temp->label == p->random->label){
                    pre->random = temp;
                }
                temp = temp->next;
            }
            pre = pre->next;
            p = p->next;
        }
        
        return newHead;
    }
};

若对上面这种做法的时间复杂度不满意,可以使用空间换时间的方法,在第一次遍历构建骨架时就将对应的random域信息存在一个数组中,将新建结点的信息存在另一数组中,这样在第二次遍历时只用一重循环即可找到对应的random域。这样做时间复杂度为O(n),空间复杂度为O(n)。 这里又个小坑,最开始为了追求代码简洁,在while循环中使用了形如array[i++]这种形式的写法,但是会导致结果与预想的不符。最后还是老老实实的用array[i];i++;这种形式,这样结果就正常了。偷懒需谨慎。

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    RandomListNode* Clone(RandomListNode* pHead) {
        if(!pHead){
            return nullptr;
        }
        RandomListNode* newHead = new RandomListNode(pHead->label);
        RandomListNode* p = pHead->next;
        RandomListNode* pre = newHead;
        RandomListNode* arr[100];
        int index = 0;
        arr[index] = newHead;
        int randomList[100] = {-1};
        if(pHead->random){
            randomList[index++] = pHead->random->label;
        }
        else{
            randomList[index++] = -1;
        }
        while(p){
            pre->next = new RandomListNode(p->label);
            if(p->random){
                randomList[index] = p->random->label;
            }
            else{
                randomList[index] = -1;
            }
            pre = pre->next;
            arr[index++] = pre;
            p = p->next;
        }
        pre = newHead;
        index = 0;
        while(pre){
            if(randomList[index] == -1){
                index++;
                pre->random = nullptr;
                pre = pre->next;
                continue;
            }
            pre->random = arr[randomList[index]-1];
            pre = pre->next;
            index++;
        }
        return newHead;
    }
};