leetcode 138. Copy List with Random Pointer
来源:互联网 发布:做生日快乐的软件 编辑:程序博客网 时间:2024/06/05 11:44
Description:
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.
加上了一个随机指针的链表,随机指针会随机地指向链表中的任意一个节点或者NULL,要求实现深拷贝。
Solution:
一开始理解错题意了,以为random指针还是直接指向原来的地址即可,后面细细一想,发现并没有那么简单。
这题也出现在《剑指offer》这本书上,看了解法之后越来越觉得这是一个好题,经典题,此题有三种解法,从坏到好一一细说:
Ⅰ超级暴力法。
1、其实难点就是在于我们不知道random指针指向的是哪个节点,既然不知道,那么我们就逐一遍历找到它指向的是第几个节点;
2、在深拷贝时,我们先实现好基本不包括random指针的链表;
3、之后在对原链表进行遍历找出每个的random指针指向的是第几个节点,然后找到新链表对应的下标节点,即可。
时间复杂度为O(n²),空间复杂度为O(1)
Ⅱ map实现(哈希表)
1、我们其实不需要random指向的是第几个节点,我们只需要建立好一个新节点与旧节点的一一对应关系即可;
2、建立好了之后,我们通过random指向的旧节点和map对应关系就能知道新节点的地方。
时间复杂度为O(n),空间复杂度为O(n)
Ⅲ O(1)空间复杂度实现
假如原链表表示为A(C)->B(A)->C(A)->NULL,括号里表示为随机指向的节点;
1、我们先将链表拷贝成如此:
A(C)->A’->B(A)->B’->C(A)->C’->NULL
即将旧链表的每一个节点的next指针指向新链表对应节点,换句话说,就是将新链表间隔地插入旧链表中。
2、拷贝random指针,执行了第一步之后,我们需要找random指针就好找许多,如下:
oldnode->next->random=oldnode->random->next
完成拷贝之后链表如下:
A(C)->A’(C’)->B(A)->B’(A’)->C(A)->C’(A’)->NULL
3、将新链表和旧链表分离即可,得到两个链表:
A(C)->B(A)->C(A)->NULL
A’(C’)->B’(A’)->C’(A’)->NULL
如此做的做法时间复杂度为O(n),空间复杂度为O(1)
Code:
Ⅱ:
class Solution {public: RandomListNode *copyRandomList(RandomListNode *head) { map<RandomListNode*, RandomListNode*> newold; RandomListNode* oldtemp = head; if (head == NULL) return head; RandomListNode* pre = NULL; RandomListNode* newhead = NULL; while (head) { RandomListNode* cur = new RandomListNode(head->label); newold[head] = cur;//build a relationship between new nodes and old nodes if (pre) pre->next = cur; else newhead = cur; pre = cur; head = head->next; } while (oldtemp) { newold[oldtemp]->random=newold[oldtemp->random]; oldtemp=oldtemp->next; } return newhead; }};
Ⅲ:
class Solution {public: RandomListNode *copyRandomList(RandomListNode *head) { RandomListNode* temp=head; if(!head) return head; while(temp) { RandomListNode* align=new RandomListNode(temp->label); align->next=temp->next; temp->next=align; temp=align->next; }//the first step temp=head; while(temp) { if(temp->random) temp->next->random=temp->random->next; temp=temp->next->next; }//the second step temp=head; RandomListNode* ans=temp->next; while(temp) { RandomListNode* al=temp->next; temp->next=al->next; temp=al->next; if(al->next) al->next=al->next->next; }//split new link and old link return ans; }};
- LeetCode 138. Copy List with Random Pointer
- [Leetcode] 138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- [leetcode] 138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- leetcode.138. Copy List with Random Pointer
- LeetCode-138.Copy List with Random Pointer
- Leetcode 138. Copy List with Random Pointer
- [Leetcode]138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- [LeetCode] 138. Copy List with Random Pointer
- [LeetCode]138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- Leetcode-138. Copy List with Random Pointer
- Leetcode 138. Copy List with Random Pointer
- leetcode 138. Copy List with Random Pointer
- Leetcode 138. Copy List with Random Pointer
- Spring之事务管理TranscationManager(大合集)
- CentOS7 下安装redis简单步骤
- 数据库范式
- fieldSerialize 序列化 加码 解码
- 如何在不知道xml结构时用jdom解析
- leetcode 138. Copy List with Random Pointer
- java properties使用
- 自定义viewgroup的个人理解和参考网络的小demo
- Eclipse关联Git的方法和步骤
- Kibana5.x (x-pack) 基本操作
- DPDK内存管理-----(四)rte_mbuf
- 通过动态获取资源ID,执行接口回调-----来实现日夜模式切换
- Java学习二
- 移动端自适应问题