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 将每一个节点的地址(key)和在链表中的位置(value)组成的key-value插入map,这样之后通过查找random对应的value就可以知道random所指向的节点的位置(下标从0索引);
1.2 新建并复制每一个节点的label,next和random指针均为NULL,将新建节点的地址依次插入vector,这样之后就可以通过random所指向的节点的位置获取节点的地址。 - 第二次遍历原始链表也做两件事:
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)的解法,构思非常巧妙:
- 每一个原始链表的节点后面新建一个拷贝节点,e.g.
1->2->3
变为1->1->2->2->3->3
。此时拷贝节点的random均为NULL。 - 将拷贝节点的random指向正确的位置。
- 将链表拆开成为两条链表,返回拷贝链表。
具体代码实现如下:
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
- LeetCode[Linked List]: Copy List with Random Pointer
- [leetcode][list] Copy List with Random Pointer
- Leetcode: Copy List with Random Pointer
- LeetCode: Copy List with Random Pointer
- [LeetCode] Copy List with Random Pointer
- [leetcode]Copy List with Random Pointer
- LeetCode:Copy List with Random Pointer
- leetcode Copy List with Random Pointer
- LeetCode:Copy List with Random Pointer
- LeetCode题解:Copy List with Random Pointer
- [LeetCode]Copy List with Random Pointer
- leetcode Copy List with Random Pointer
- leetcode-Copy List with Random Pointer
- Leetcode: Copy List with Random Pointer
- LeetCode | Copy List with Random Pointer
- [LeetCode] Copy List with Random Pointer
- LeetCode OJ:Copy List with Random Pointer
- LeetCode(138)Copy List with Random Pointer
- hdu 4059 The Boss on Mars(容斥)
- 分享一个链接
- 产品黑魔法:腾讯搞流量的重要一课
- Hdu 5090 Game with Pearls(二分匹配)
- @Response
- LeetCode[Linked List]: Copy List with Random Pointer
- 高仿新闻教程-开源框架的简单实现——网易新闻的标题栏(一)
- 一个可以解析复杂JSON字符串里面值的算法
- hdu 5087 Revenge of LIS II | dp 次长上升子序列
- android中viewpager的学习
- 淘宝爆款女性减肥瘦身产品大集成大排行
- Shell编程学习笔记
- nyoj891(区间上的贪心)
- java基础_IO