【LeetCode】Copy List with Random Pointer

题目:

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.

Return a deep copy of the list.

分析:

我们知道如果是简单的copy List 的话,那么我们只需要从头到尾遍历下来,new出对应个数的Node,并把它们的连接关系设置好就可以了,但是这道题目中每个节点Node出现了Random属性,也就意味着可能当前结点Node所依赖的那个Random对应的结点还没有被创建出来。


解题思路:

为了解决“分析”里提到的问题,我们需要做如下三步处理!

1. 在OldList中的每个结点后,插入一个CopyNode,这个结点的Random域和Next域与OldList中的被拷贝Node的Random域和Next一致,然后让被拷贝结点的Next域指向CopyNode结点,这样先创建出OldList中结点对应的CopyNode结点。

2. 由于所有的CopyNode都已经创建出来了,我们就可以调整这些CopyNode真正的Random域的值了。

3. 调整所有CopyNode的Next域的值,恢复OldList所有Node的Next的值到初始状态!

不能把第二步和第三部一起来处理,因为后面的结点可以指到前面,而前面的结点已经断开了,其random指针的next是原来的List,故报错。

package copylist;
class RandomListNode {
    int label;
    RandomListNode next, random;
    RandomListNode(int x) { this.label = x; }
};

public class Solution {
    public RandomListNode copyRandomList(RandomListNode head) {
    	
    	if (head == null)
    		return head;
    	/*第一步:在OldList的每个节点后面都插入一个copyNode(拷贝链表的结点)*/
    	RandomListNode nowNode = head;
    	while (nowNode != null){
    		RandomListNode copyNode = new RandomListNode(nowNode.label);
    		copyNode.random = nowNode.random;
    		copyNode.next = nowNode.next;
    		nowNode.next = copyNode;
    		nowNode = nowNode.next.next;
    	}
    	
    	/*第二步:确定NewList的每个节点,真正关联到的Random结点是哪个,
    	 * 		因为第一步已经把所有NewList上的结点都建立了*/
    	nowNode = head;
    	while (nowNode != null){
    		if (nowNode.random != null){
    			nowNode.next.random = nowNode.random.next;
    		}
    		nowNode = nowNode.next.next;
    	}
    	
    	/*第三步:还原OldList的next为一开始的next结点
    	 * 		并拼接NewList的next到它真正所应该关联的next结点
    	 * 		即:保持老链表OldList不变,拼接新链表NewList!
    	 * */
    	RandomListNode pHead = new RandomListNode(0);
    	pHead.next = head;
    	RandomListNode newlist = pHead;
    	
    	nowNode = head;
    	while (nowNode != null){
    		pHead.next = nowNode.next;
    		nowNode.next = pHead.next.next;
    		pHead = pHead.next;
    		nowNode = nowNode.next;
    	}
    	return newlist.next;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值