# 剑指offer第二版-35.复杂链表的复制

``````package chapter4;
import java.util.HashMap;

/**
* Created by ryder on 2017/7/18.
* 复制复杂链表
*/
public class P187_CopyComplexList {
public static class ComplexListNode{
int val;
ComplexListNode next;
ComplexListNode random;

public ComplexListNode(int val) {
this.val = val;
}
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
ComplexListNode cur = this;
while(cur!=null) {
ret.append(cur.val);
if(cur.random!=null)
ret.append("("+cur.random.val+")");
else{
ret.append("(_)");
}
ret.append('\t');
cur = cur.next;
}
return ret.toString();
}
}
//解法一
//time:o(n^2) space:o(1) 新链表使用的n个长度的空间不算入
//先复制val与next（时间o(n)），再复制random域（时间o(n^2)）
return null;
ComplexListNode newCur = null;
while (cur!=null){
newCur = new ComplexListNode(cur.val);
newCurPrev.next = newCur;
newCurPrev = newCurPrev.next;
cur = cur.next;
}
while(cur!=null){
if(cur.random!=null){
while (temp!=cur.random){
temp = temp.next;
newTemp = newTemp.next;
}
newCur.random = newTemp;
}
cur = cur.next;
newCur = newCur.next;
}
}
public static void main(String[] args){
ComplexListNode c2 = new ComplexListNode(2);
ComplexListNode c3 = new ComplexListNode(3);
ComplexListNode c4 = new ComplexListNode(4);
ComplexListNode c5 = new ComplexListNode(5);
}
}
``````

``````    //解法二
//time:o(n) space:o(n)
//使用o(n)的空间，换取了时间复杂度的降低
public static ComplexListNode clone2(ComplexListNode head) {
return null;
HashMap<ComplexListNode,ComplexListNode> oldToNew = new HashMap<>();
ComplexListNode newCur = null;
while (cur!=null){
newCur = new ComplexListNode(cur.val);
oldToNew.put(cur,newCur);
newCurPrev.next = newCur;
newCurPrev = newCurPrev.next;
cur = cur.next;
}
while(cur!=null){
if(cur.random!=null){
newCur.random = oldToNew.get(cur.random);
}
cur = cur.next;
newCur = newCur.next;
}
}
``````

1）cloneNodes完成新链表节点的创建，仅对val域赋值，且每个新节点接在原链表对应节点的后面。如A->B->C,处理完后为A->A'->B->B'->C->C'，时间复杂度o(n)。
2）connectRandomNode完成random域的赋值。假设A.random=C,我们需要设置A'.random=C'，此处获取C'可以在o(1)的时间复杂度完成，全部赋值完毕时间复杂度为o(n)。
3）reconnectNodes就是将上述链表重组，使A->A'->B->B'->C->C'变为A->B->C，A'->B'->C'。此处需要注意尾部null的处理。

``````    //解法三
//time:o(n) space:o(1)
public static ComplexListNode clone3(ComplexListNode head) {
return null;
}
ComplexListNode temp = null;
while (cur!=null){
temp = new ComplexListNode(cur.val);
temp.next = cur.next;
cur.next = temp;
cur = cur.next.next;
}
}
while (true){
if(cur.random!=null)
curNext.random = cur.random.next;
cur = cur.next.next;
if(cur == null)
break;
curNext = curNext.next.next;
}
}
while (true){
cur.next = cur.next.next;
cur = cur.next;
if(cur==null){
newCur.next = null;
break;
}
newCur.next = newCur.next.next;
newCur = newCur.next;
}
}
``````

``````original:   1(3)    2(5)    3(_)    4(2)    5(_)
clone1:     1(3)    2(5)    3(_)    4(2)    5(_)
clone2:     1(3)    2(5)    3(_)    4(2)    5(_)
clone3:     1(3)    2(5)    3(_)    4(2)    5(_)
``````

### 推荐阅读更多精彩内容

• 总结 想清楚再编码 分析方法：举例子、画图 第1节：画图分析方法 对于二叉树、二维数组、链表等问题，都可以采用画图...
M_巴拉巴拉阅读 914评论 0 7
• 转载请注明出处：http://www.jianshu.com/p/c65d9d753c31 在上一篇博客《数据结构...
Alent阅读 2,940评论 3 73
• //leetcode中还有花样链表题，这里几个例子，冰山一角 求单链表中结点的个数----时间复杂度O（n）这是最...
暗黑破坏球嘿哈阅读 811评论 0 6
• 辟谷日记：当身体自己不想吃东西的时候开始辟谷，但是不断食，辟谷只是不吃五谷杂粮但是蔬菜和水果还是想吃的。第一天辟谷...
偶然来到的猫阅读 136评论 0 0
• 夜之旅，我们相识在2014.3.18日。
鲋鱼阅读 26评论 0 0