十三.复制含有随机指针节点的链表

【题目】

一种特殊的链表节点类描述如下:
public class Node { public int value; public Node next; public
Node rand;
public Node(int data) { this.value = data; }
}
Node类中的value是节点值,next指针指向下一个节点,rand指针可能指向链表中的任意一个节点,也可能指向null。
给定一个由Node节点类型组成的无环单链表的头节点head,请实现一个函数完成这个链表中所有结构的复制,并返回复制的新链表的头节点。

【进阶】

不使用额外的数据结构,只用有限几个变量,且在时间复杂度为 O(N)内完成原问题要实现的函数。

【分析】

我们可以用hashMap存储键值对来时间链表结构的复制。(需要哈希表,所以有额外的数据空间)
1.遍历链表中所有的节点,作为hashMap中的键存进去;
2.hashMap中的值就是对应键的复制节点;
3.我们复制的结构是:通过键(原来的节点)找到值(复制的节点);
通过原来链表中的指向关系找到下一个结点;
把这个节点作为键找到对应的值(就是后一个的复制节点),建立指向关系。
4.随机指针同理。

【代码实现】

public static Node  copyListWithRand1(Node head) {
		HashMap<Node, Node> map=new HashMap<>();
		Node cur=head;
		while(cur!=null) {
			map.put(cur, new Node(cur.value));
			cur=cur.next;
		}
		
		cur=head;
		while(cur!=null) {
			map.get(cur).next=map.get(cur.next);
			map.get(cur).rand=map.get(cur.rand);
		}
		return map.get(head);
	}

【进阶分析】

1.每两个节点之间插入前一个结点的复制节点
2.复制节点的随机节点指向问题
3.断开原链表和复制链表

【代码实现】

public static Node  copyListWithRand2(Node head) {
		if (head==null) {
			return null;
		}
		Node cur=head;
		
		//next用来保存的是当前操作节点的下一个结点
		Node next=null;
		
		//1.完成复制结点和next指针指向
		while(cur!=null) {
			next=cur.next;//保存住当前操作节点的下一个结点
			cur.next=new Node(cur.value);//当前操作节点指向他的复制节点
			cur.next.next=next;//当前操作节点的复制节点指向的是原来next保留住的节点
			cur=next;//移动,进行下一个结点的操作
		}
		
		//2.完成随机指针指向
		cur=head;
		Node curCopy=null;
		while(cur!=null) {
			next=cur.next.next;//保存原链表中下一个结点,为了控制指针的移动
			curCopy=cur.next;//保存原链表中的复制节点
			curCopy.rand=cur.rand!=null?cur.rand.next:null;//复制节点随机指向原来随机指向的下一个位置
			cur=next;//进行下一个节点的操作
		}
		
		//3.完成原链表和复制链表的分裂
		Node res=head.next;//第一个复制节点,同时也是要返回的值
		cur=head;
		while(cur!=null) {
			next=cur.next.next;//保存住原来链表的下一个结点
			curCopy=cur.next;//保存住复制节点
			cur.next=next;//原来节点指向原链表中他的下一个结点
			curCopy.next=next!=null?next.next:null;//原来节点的复制节点指向的是原来下一个结点的下一位
			cur=next;//移动当前操作指针。
		}
		return res;
	}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下 4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值