[LeetCode OJ] Copy List with Random Pointer 扩大
职务地址:https://oj.leetcode.com/problems/copy-list-with-random-pointer/
题意:对一个有回路的链表的深复制
解题:这道题我AC了之后才发现理解错了题意,然后就參考了以下这篇文章。
假设想看这道题的解题思路的话,请移步http://www.2cto.com/kf/201310/253477.html
拓展:假如题目给的节点不是链表的头节点。而是链表中的随意一个节点,在保证从给的点能遍历所有节点的情况下,深复制这个链表。
那么该怎么做呢?
思路:事实上一想,和原题的区别仅仅有节点是否是头节点而已,那么我们就从给的这个节点找到原节点即可了。
遍历的过程用dfs,再用map来推断一个节点是否被遍历过。如今唯一的难点就是怎样找到头节点,这里用并查集就OK了。
路径压缩后并查集的复杂度接近O(1),因为map的复杂度接近O(logN),这样dfs的复杂度大概是O(NlogN)。
技巧:dfs到一个新的节点时,用map将其映射成一个唯一的整数cnt,并在这时初始化并查集fa[cnt]。
//#include "stdafx.h"
#include<iostream>
#include<string.h>
#include <map>
#include<set>
using namespace std;
int fa[10024];//节点数
inline int findfa(int x){
if(fa[x] == x) return x;
while(x!=fa[x]){
x=fa[x];
}
return x;
} inline int merge(int x,int y){
int fa1=findfa(x), fa2=findfa(y);
if(fa1!=fa2){
fa[fa2] = fa1;
}
return fa1;
} struct RandomListNode {
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
}; class Solution {
map<RandomListNode*,int> mp;
map<RandomListNode*,int>::iterator it;
int cnt;
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if(!head) return head;
/***********凝视部分是拓展的解法************
init();
dfs(head,1);
int faNum = findfa(1);
for(it=mp.begin();it!=mp.end();++it){
if(it->second == faNum){
head = it->first;
break;
}
}
***********************************************/
return deepCopy(head);
}
void init(){
memset(fa,0,sizeof(fa));
cnt=0; }
void dfs(RandomListNode *ptr, int faCnt){
if(ptr == NULL) return;
it=mp.find(ptr);
if(it!=mp.end()) return; mp[ptr] = ++cnt;
fa[cnt] = cnt;//初始化
fa[cnt] = findfa(faCnt>0? faCnt:cnt);
RandomListNode *next = ptr->next;
RandomListNode *random = ptr->random;
it=mp.find(next);
if(it==mp.end()){
dfs(next,faCnt>0?faCnt:cnt);
}
else{
fa[mp[next]] = fa[cnt];
} it=mp.find(random);
if(it==mp.end()){
dfs(random,0);//0表示不能确定其父节点
}
} //非拓展部分解法
RandomListNode* deepCopy(RandomListNode *head){
//在原链表上双倍复制链表
RandomListNode *ptr1 = head, *ptr2 = NULL;
while(ptr1 != NULL){
ptr2 = new RandomListNode(ptr1->label);
ptr2->next = ptr1->next;
ptr1->next = ptr2;
ptr1=ptr2->next;
} //复制原链表的random关系
ptr1 = head, ptr2 = NULL;
while(ptr1 != NULL){
ptr2 = ptr1->next;
if(ptr1->random)
ptr2->random = ptr1->random->next;
ptr1=ptr2->next;
} //将原列表分裂成两个列表
RandomListNode *H =NULL, *ptr3;
ptr1 = head, ptr2 = NULL;
while(ptr1 != NULL){
ptr2 = ptr1->next;
if(H==NULL){
H = ptr2;
ptr3 = H;
}
else{
ptr3->next = ptr2;
ptr3 = ptr2;
}
ptr1->next = ptr2->next;
ptr1 = ptr1->next;
}
return H;
}
};
版权声明:本文博客原创文章,博客,未经同意,不得转载。
[LeetCode OJ] Copy List with Random Pointer 扩大的更多相关文章
- [Leetcode Week17]Copy List with Random Pointer
Copy List with Random Pointer 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/copy-list-with-random- ...
- [LeetCode] 138. Copy List with Random Pointer 拷贝带有随机指针的链表
A linked list is given such that each node contains an additional random pointer which could point t ...
- [LeetCode] 138. Copy List with Random Pointer 拷贝带随机指针的链表
A linked list is given such that each node contains an additional random pointer which could point t ...
- Java for LeetCode 138 Copy List with Random Pointer
A linked list is given such that each node contains an additional random pointer which could point t ...
- 【leetcode】Copy List with Random Pointer (hard)
A linked list is given such that each node contains an additional random pointer which could point t ...
- leetcode 138. Copy List with Random Pointer ----- java
A linked list is given such that each node contains an additional random pointer which could point t ...
- LeetCode _ Copy List with Random Pointer
A linked list is given such that each node contains an additional random pointer which could point t ...
- 【LeetCode】Copy List with Random Pointer
A linked list is given such that each node contains an additional random pointer which could point t ...
- leetcode 【 Copy List with Random Pointer 】 python 实现
题目: A linked list is given such that each node contains an additional random pointer which could poi ...
随机推荐
- 【Redis源代码剖析】 - Redis内置数据结构之压缩字典zipmap
原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/51111230 今天为大家带来Redis中zipmap数据结构的分析,该结构定义在 ...
- 因权限引起的svn提交失败的错误及其解决办法
作者:朱金灿 来源:http://blog.csdn.net/clever101 前段时间,一个网友发邮件向我请教一个svn提交失败的错误.他的具体错误是这样的: 在配置svn强制输入日志时候遇到一个 ...
- html5+js压缩图片上传
最近在折腾移动站的开发,涉及到了一个手机里面上传图片.于是经过N久的折腾,找到一个插件,用法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
- centos-mirrors
http://mirrors.aliyun.com/centos/7.2.1511/os/x86_64/Packages/ http://mirrors.aliyun.com/centos/7.2.1 ...
- php中foreach源码分析(编译原理)
php中foreach源码分析(编译原理) 一.总结 编译原理(lex and yacc)的知识 二.php中foreach源码分析 foreach是PHP中很常用的一个用作数组循环的控制语句.因为它 ...
- CVE-2014-3566
https://access.redhat.com/articles/1232123 https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv ...
- 编辑器vim简介
vi简介 vi是"Visual interface"的简称,它在Linux上的地位就仿佛Edit程序在DOS上一样.它可以执行输出.删除.查找.替换.块操作等众多文本操作,而且用户 ...
- 一步步学习Linux多任务编程
系统调用 01.什么是系统调用? 02.Linux系统调用之I/O操作(文件操作) 03.文件描述符的复制:dup(), dup2() 多进程实现多任务 04.进程的介绍 05.Linux可执行文件结 ...
- 进入Erlang的世界
http://erlang.group.iteye.com/group/wiki/1407-to-enter-the-world-of-erlang 进入Erlang的世界 作为程序员,我们曾经闻听很 ...
- WPF 针对数据源某个属性进行排序
原文:WPF 针对数据源某个属性进行排序 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wanlong360599336/article/detai ...