职务地址: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 扩大的更多相关文章

  1. [Leetcode Week17]Copy List with Random Pointer

    Copy List with Random Pointer 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/copy-list-with-random- ...

  2. [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 ...

  3. [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 ...

  4. 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 ...

  5. 【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 ...

  6. 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 ...

  7. LeetCode _ Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  8. 【LeetCode】Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  9. leetcode 【 Copy List with Random Pointer 】 python 实现

    题目: A linked list is given such that each node contains an additional random pointer which could poi ...

随机推荐

  1. Android应用开发按下返回键退向后台执行

    转载请注明来源:http://blog.csdn.net/kjunchen/article/details/50429694 Android应用开发按下返回键退向后台执行 我们日常使用的非常多Andr ...

  2. swift学习第八天:元组

    元组的介绍 元组是Swift中特有的,OC中并没有相关类型 它是什么呢? 它是一种数据结构,在数学中应用广泛 类似于数组或者字典 可以用于定义一组数据 组成元组类型的数据可以称为“元素” 元组的定义 ...

  3. 【PHP】php 递归、效率和分析(转)

    递归的定义 递归(http:/en.wikipedia.org/wiki/Recursive)是一种函数调用自身(直接或间接)的一种机制,这种强大的思想可以把某些复杂的概念变得极为简单.在计算机科学之 ...

  4. 复制相关参数学习笔记--master上的参数

    特别声明: 所有的过滤规则不建议在主库上设置.     server_id 是一个整数,范围:1 至 power(2,32)-1 之间. 推荐使用端口号+ip最后一位的方式. 唯一区别ID,同一个集群 ...

  5. 【u006】海战

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞 ...

  6. 后台报错java.lang.IllegalArgumentException: Invalid character found in the request target.

    报错: Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level. java.lang ...

  7. Oracle成长点点滴滴(2)— 权限管理

    权限管理中权限包含系统权限以及对象权限.在解说权限管理之前我们先来了解用户的创建以及授权这些前提. 1.      创建用户以及授权 Ø  默认用户 既然提到了创建用户,首先必须先把用户的知识攻克了. ...

  8. C++ public、protected、private 继承方式的区别

    访问修饰符 public.protected.private,无论是修饰类内成员(变量.函数),还是修饰继承方式,本质上实现的都是可见性的控制. Difference between private, ...

  9. TCP协议的一些认识及实践

    http://www.2cto.com/net/201210/163047.html 一.简介 引用<TCP/IP详解-卷1>中的介绍,TCP与UDP使用相同的网络层(IP层),TCP却向 ...

  10. 从华为产品学到什么是devops

    根据Gartner 2015 I&O Automation 报告,DevOps处于技术发展的最高点,实践受到高度关注,到底devops魔力在哪里? 从devops实践看主要是打破开发人员和运营 ...