[LeetCode] 138. Copy List with Random Pointer

原题链接: https://leetcode.com/problems/copy-list-with-random-pointer/

1. 题目介绍

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.
给定一个链表,这个链表的每个节点都包含了一个额外的随机指针。这个随机指针可以指向任意节点或者null。
Return a deep copy of the list.
返回一个链表的深拷贝。

什么是链表的深拷贝呢?这要从链表的存储形式说起了。
内存分为两个空间,一个是堆内存,一个是栈内存。实例化的类都放在堆内存中,指向它们的引用(指针)存放在栈内存中。
比如:下面这一段代码

Node a = new Node(3,null,null);
Node b = a;
Node c = new Node(3,null,null);

Node(3,null,null) 经过实例化,存储在堆内存中。 a 存放在堆内存中,a 指向堆内存中Node(3,null,null) 那片空间。
这时候让 b = a,相当于a 、b 指向了同一块堆内存空间,b. val = a . val 。修改了a.val,也会改变 b.val .这是对a的浅拷贝。
如果这时候,在堆内存中新开辟一块空间,存储和 a 指向的Node(3,null,null) 一样的内容,并且这块新开辟的空间由 c 指向。a、c指向两个不同的空间。这时虽然 c. val = a . val。但是如果改变 c.val , a.val 是不会改变的。这是对 a 的深拷贝。

所以本题可以简单概括为,重新在堆内存中做一个和原有链表一模一样的链表,两者只是内容相同。修改其中一个链表,不会改变另外的链表。

Example 1:
在这里插入图片描述

在这里插入图片描述
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。

Note:
You must return the copy of the given head as a reference to the cloned list.
必须返回深拷贝的链表头节点引用。

2. 解题思路

本题的做法参考了题目中的 Hint 3、4:
We can avoid using extra space for old node —> new node mapping, by tweaking the original linked list. Simply interweave the nodes of the old and copied list.
For e.g.
Old List: A --> B --> C --> D
InterWeaved List: A --> A’ --> B --> B’ --> C --> C’ --> D --> D’
The interweaving is done using next pointers and we can make use of interweaved structure to get the correct reference nodes for random pointers.

具体做法是,首先让每个节点后面都接上一个自己的复制节点。然后串联起来所有的复制节点,就完成了对原链表的深拷贝。

实现代码

class Solution {
    public Node copyRandomList(Node head) {
		if (head == null) {
			return null;
		}
		//让每个节点后面有一个和自己一样的复制节点
		Node cur = head;
		while(cur != null){
			cur.next = new Node(cur.val , cur.next , cur.random);
			cur = cur.next.next;
		}
		
		//让复制节点的 random 指向原来 random 的复制节点
		cur = head;
		while(cur != null ){
			cur.next.random = ( cur.random == null ? null : cur.random.next);
			cur = cur.next.next;
		}
		
		//恢复原来的链表,分离复制节点组成的深拷贝
		cur = head;
		Node res = head.next;
		while(cur != null){
			Node temp = cur.next;
			cur.next = temp.next;
			if (temp.next != null) {
				temp.next = temp.next.next;
			}
			cur =cur.next;
		}
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值