LeetCode[Linked List]: Copy List with Random Pointer

来源:互联网 发布:阿里云注销备案 编辑:程序博客网 时间:2024/06/08 05:17

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.

/** * 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) {} * }; */

我的解题思路如下:

  1. 第一次遍历原始链表做两件事:
    1.1 将每一个节点的地址(key)和在链表中的位置(value)组成的key-value插入map,这样之后通过查找random对应的value就可以知道random所指向的节点的位置(下标从0索引);
    1.2 新建并复制每一个节点的label,next和random指针均为NULL,将新建节点的地址依次插入vector,这样之后就可以通过random所指向的节点的位置获取节点的地址。
  2. 第二次遍历原始链表也做两件事:
    2.1 将新建节点通过next指针串联起来成为复制链表;
    2.2 对于每一个原始节点:在map中查找该节点的random所指向的节点的位置,通过该位置在vector中得到新建链表中对应节点的地址,将该地址赋给复制节点的random即可。

代码实现如下:

    RandomListNode *copyRandomList(RandomListNode *head) {        if (!head) return head;        map<RandomListNode *, int> positions;        vector<RandomListNode *> cpyList;        int pos = 0;        for (RandomListNode *curr = head; curr != NULL; curr = curr->next, ++pos) {            positions.insert(pair<RandomListNode *, int> (curr, pos));            RandomListNode *newNode = new RandomListNode(curr->label);            cpyList.push_back(newNode);        }        cpyList.push_back(NULL);        pos = 0;        for (RandomListNode *curr = head; curr != NULL; curr = curr->next, ++pos) {            cpyList[pos]->next   = cpyList[pos + 1];            cpyList[pos]->random = curr->random ? cpyList[positions[curr->random]] : NULL;        }        return cpyList[0];    }


上面代码的时间复杂度是O(N),空间复杂度是O(N)
Discuss上寻求更好的解法,看到一个空间复杂度为O(1)的解法,构思非常巧妙:

  1. 每一个原始链表的节点后面新建一个拷贝节点,e.g. 1->2->3变为1->1->2->2->3->3此时拷贝节点的random均为NULL
  2. 将拷贝节点的random指向正确的位置。
  3. 将链表拆开成为两条链表,返回拷贝链表。

具体代码实现如下:

    RandomListNode *copyRandomList(RandomListNode *head) {        if(head == NULL) return NULL;        RandomListNode *p = head;        while(p != NULL) {            RandomListNode *q = p->next;            p->next = new RandomListNode(p->label);            p->next->next = q;            p = q;        }        for (p = head; p != NULL; p = p->next->next)            p->next->random = (p->random == NULL) ? NULL : p->random->next;        p = head;        RandomListNode *r = head->next;        for(RandomListNode *q = r;;) {            p->next = q->next;            p = p->next;            if(p == NULL) break;            q->next = p->next;            q = q->next;        }        return r;    }


0 0
原创粉丝点击