package java_jianzhioffer_algorithm;
/**
* 题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),
* 返回结果为复制后复杂链表的head。
* (注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
* @author hexiaoli
* 思路:
* 不采用空间换时间的方法。
* 1)复制复杂链表。把复制结点跟在原结点后面,而不直接创建新的链表;
* 2)设置复制出来的结点的random。因为原结点与复制结点是前后对应关系,所以原结点的random的后一个结点即为复制结点的random
* 3)拆分链表。奇数位为原链表,偶数位为复制链表。
*/
class RandomListNode{
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
public class Clone {
public static RandomListNode clone(RandomListNode pHead) {
if(pHead == null) {
return null;
}
//第一步:复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
RandomListNode currentNode = pHead;
while(currentNode!=null) {
// 创建复制结点
RandomListNode cloneNode = new RandomListNode(currentNode.label);
// 定义当前结点的后一个结点
RandomListNode nextNode = currentNode.next;
// 将复制结点链接到当前结点的后面
currentNode.next=cloneNode;
// 将原先的后一个结点链接到复制节点后面
cloneNode.next=nextNode;
// 将指针移动到下一个结点
currentNode =nextNode;
}
//第二步:重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next;
// 将当前指针重新指向原链表头
currentNode = pHead;
while(currentNode!=null){
// 判断当前结点是否存在随机指针,如果存在,则将当前结点的下一个结点(即复制结点)的随机指针
// 指向当前结点的随机结点的后一个结点(即随机指针的复制结点)
currentNode.next.random = currentNode.random==null?null:currentNode.random.next;
// 将指针移动到下下个结点(因为下一个是复制结点)
currentNode = currentNode.next.next;
}
// 将当前指针重新指向原链表头
currentNode = pHead;
// 定义复制链表的表头为原链表头的下一个结点
RandomListNode pCloneHead = pHead.next;
while(currentNode!=null) {
// 定义复制链表的指针指向的结点为当前指针指向结点的后一个
RandomListNode cloneNode = currentNode.next;
// 将当前复制结点的后一个结点(即原本链表的后一个结点)重新链接回当前结点
currentNode.next = cloneNode.next;
// 链接复制结点的下下个结点
cloneNode.next = cloneNode.next == null ? null : cloneNode.next.next;
// 将指针移动到后一个结点(因为复制结点已从链表中断出)
currentNode = currentNode.next;
}
return pCloneHead;
}
public static void main(String[] args) {
RandomListNode pHead = new RandomListNode(1);
RandomListNode p1 = new RandomListNode(2);
RandomListNode p2 = new RandomListNode(3);
RandomListNode p3 = new RandomListNode(4);
RandomListNode p4 = new RandomListNode(5);
RandomListNode p5 = new RandomListNode(6);
pHead.next=p1;
p1.next=p2;
p2.next=p3;
p3.next=p4;
p4.next=p5;
p1.random=p4;
p2.random=p5;
RandomListNode resultNode;
resultNode=clone(pHead);
System.out.println(resultNode.label);
}
}
剑指offer(25)复杂链表的复制
猜你喜欢
转载自blog.csdn.net/hxl0925/article/details/90401437
今日推荐
周排行