题目描述:

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的深度拷贝。

  

思路:

先遍历链表,将每个节点对应的随机指针指向的对象利用HashMap存起来,key的值就为节点的在链表里面的位置,Value的值是随机指针指向的对象

再把原链表的节点对应的在链表中的位置存起来,key为节点对象,然后将节点的label取出来新建节点,存起来

再次遍历链表,处理随机指针

这是第一种用HashMap的办法,但是性能不行,还有优化的空间,之后我再研究研究看能不能改改

public static RandomListNode copyRandomList(RandomListNode head) {
HashMap<Integer,RandomListNode> randomMap = new HashMap<>();//随机节点
HashMap<Integer,RandomListNode> newMap = new HashMap<>();//新的节点
HashMap<RandomListNode,Integer> oldMap = new HashMap<>();//原表的节点 RandomListNode result = head; if(head==null)
return head;
if(head.next==null){
RandomListNode it = new RandomListNode(head.label);
if (head.random!=null){
it.random = it;//指向自己
}
return it;
}
//迭代
RandomListNode iterator = head;
int i = 0;
while(iterator!=null){
//将第几位对应的随机指针存起来
randomMap.put(i,iterator.random);
//原链表节点对应的位置存起来
oldMap.put(iterator,i);
//新建节点,复制
RandomListNode node = new RandomListNode(iterator.label);
newMap.put(i,node);
if(i==0){
//第一个
result = node;
}
iterator = iterator.next;
i++;
}
i = 0;
iterator = head;
while(iterator!=null){
if(i>0)
newMap.get(i-1).next = newMap.get(i);
//检测原节点的随机指针是否为空
if(oldMap.get(randomMap.get(i))!=null){
//获得原链表节点的随机指针指向的对象的位置
int random = oldMap.get(randomMap.get(i));
//赋值
newMap.get(i).random = newMap.get(random);
}else {
//随机指针为空的情况
newMap.get(i).random = null;
}
iterator = iterator.next;
i++;
}
return result;
} static class RandomListNode {
int label;
RandomListNode next, random;
RandomListNode(int x) { this.label = x; }
}

  

第二种办法,先将节点复制,插入到被复制的节点的后面,然后将随机节点加入进去,之后拆分链表

import java.util.*;
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if (pHead==null)
return null;
RandomListNode current = pHead;
//将复制的节点插入
while (current!=null){
RandomListNode clone = new RandomListNode(current.label);
RandomListNode next = current.next;
current.next = clone;
clone.next = next;
current = next;
}
//将随机节点加入
current = pHead;
while (current!=null){
current.next.random = current.random==null?null:current.random.next;//指向新的随机节点
current = current.next.next;
}
//拆分
current = pHead;
RandomListNode res = pHead.next;
while (current!=null){
RandomListNode clone = current.next;
current.next = clone.next;
clone.next = clone.next==null?null:clone.next.next;
current = current.next;
}
return res;
}

  

[LeetCode]138复制带随机指针的链表的更多相关文章

  1. Java实现 LeetCode 138 复制带随机指针的链表

    138. 复制带随机指针的链表 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点. 要求返回这个链表的 深拷贝. 我们用一个由 n 个节点组成的链表来表示输入/ ...

  2. LeetCode 138——复制带随机指针的链表

    1. 题目 2. 解答 第一次遍历链表的时候,复制旧链表的节点值建立一个新的链表,同时定义一个 unordered_map 作为哈希表,哈希表的键为旧链表的节点指针,值为新链表的节点指针. 然后,第二 ...

  3. Leetcode 138. 复制带随机指针的链表

    1.题目要求 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点. 要求返回这个链表的深度拷贝. 2.解题思路 (1)笔试思路(求速度,拿分数):使用哈希表 /* ...

  4. 【leetcode 138. 复制带随机指针的链表】解题报告

    方法一:递归 unordered_map<Node*,Node*> dict; Node* copyRandomList(Node* head) { if (!head) return h ...

  5. LintCode-105.复制带随机指针的链表

    复制带随机指针的链表 给出一个链表,每个节点包含一个额外增加的随机指针可以指向链表中的任何节点或空的节点. 返回一个深拷贝的链表. 挑战 可否使用O(1)的空间 标签 哈希表 链表 优步 code / ...

  6. LeetCode 138:复制带随机指针的链表 Copy List with Random Pointer

    给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点. 要求返回这个链表的深拷贝. A linked list is given such that each no ...

  7. 【LeetCode】138. Copy List with Random Pointer 复制带随机指针的链表 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人公众号:负雪明烛 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https:/ ...

  8. 138 Copy List with Random Pointer 复制带随机指针的链表

    给出一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点.返回一个深拷贝的链表. 详见:https://leetcode.com/problems/copy-list- ...

  9. [Java]LeetCode138. 复制带随机指针的链表 | Copy List with Random Pointer

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

随机推荐

  1. 2019.01.10 bzoj1095: [ZJOI2007]Hide 捉迷藏(动态点分治)

    传送门 蒟蒻真正意义上做的第一道动态点分治! 题意:给一棵最开始所有点都是黑点的树,支持把点的颜色变成从黑/白色变成白/黑色,问当前状态树上两个最远黑点的距离. 思路: 首先考虑不带修改一次点分治怎么 ...

  2. vue 开发系列(五) 调用原生API

    概要 我们在开发手机端程序的时候了,我们经常需要使用到拍照,二维码的功能.数字天堂公司提供了大量的原生API支持. http://www.html5plus.org/doc/ 实现 1.在hbuild ...

  3. MFC中的几个虚函数

    1.PreTranslateMessage()和WindowProc() PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,通过函数名也可以猜出来.绝 ...

  4. C++之基于排序方法求一组数的中位数

    中位数也就是中值: 故需要先对数组进行排序(选择,插入,冒泡排序),然后在找出数组的中值. //求中值 #include<iostream> using namespace std; in ...

  5. BZOJ 1444 [Jsoi2009]有趣的游戏 (AC自动机 + 概率DP + Gauss)

    1444: [Jsoi2009]有趣的游戏 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1382  Solved: 498[Submit][Statu ...

  6. C++指针一

    指针也是变量,占有内存空间,用来保存内存地址. 指针也是一种数据类型,指针是一种数据类型,是指它所致内存空间的数据类型. 指针变量和它指向的内存块是两个不同的概念 *p操作内存 在指针声明时,*号表示 ...

  7. spring配置Bean

    Bean   就是一个类 一下代码都是基于spring之IOC和DI实现案例基础上进行解析 Bean的实例化方式: 1.无参构造 <bean id="UserService" ...

  8. Qt_技巧_将Qt动态链接生成的exe与dll打包方法

    刚开始接触Qt,发现mac平台直接release编译一下就能够直接生成.app文件,并且可以直接运行..app位于工程文件内. 同样发方法在Windows直接运行exe却出现缺失dll情况. 讲过网上 ...

  9. kepware http接口 Objective-C开发

    读取某变量的值(NSURL #import <Foundation/Foundation.h> NSDictionary *headers = @{ @"Connection&q ...

  10. 在Echarts 柱形图的单击事件中写入自定义的参数

    标签: 逻辑:(点击柱形图的某个实例(注意:三个柱子表示的是一个实例)) 参考链接:http://echarts.baidu.com/doc/example/event.html { name: ‘c ...