题目及测试
package sword026;
/* 题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,
* 一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
* (注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空
*/
public class main {
public static void main(String[] args) {
Node a=new Node();
Node b=new Node();
Node c=new Node();
Node d=new Node();
a.val=1;
b.val=2;
a.next=b;
a.random=b;
b.random=a;
test(a);
a=new Node();
a.val=1;
test(a);
a=new Node();
b=new Node();
c=new Node();
d=new Node();
a.val=1;
b.val=2;
c.val=3;
d.val=4;
a.next=b;
b.next=c;
c.next=d;
a.random=c;
b.random=c;
c.random=null;
d.random=null;
test(a);
}
private static void test(Node ito) {
Solution solution = new Solution();
Node rtn;
long begin = System.currentTimeMillis();
System.out.println();
//开始时打印数组
rtn=solution.copyRandomList(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn=");
while(rtn!=null){
System.out.println(rtn+" "+rtn.val+" "+rtn.next+" "+rtn.random);
rtn=rtn.next;
}
//System.out.println(":rtn" );
//System.out.print(rtn);
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功)
第一步:让仍然是根据原始链表的每个结点N创建对应的N'。不过我们把N’链接在N的后面。
第二步:设置复制出来的结点的m_pSibling。原始链表上的A的m_pSibling指向结点C,那么其对应复制出来的A’是A的m_pNext指向的结点,同样C’也是C的m_pNext指向的结点。即A' = A.next,A'.m_pSibling = A.m_pSibling.next;故像这样就可以把每个结点的m_pSibling设置完毕。
第三步:将这个长链表拆分成两个链表:把奇数位置的结点用m_pNext链接起来就是原始链表,把偶数位置的结点用m_pNext链接起来就是复制出来的链表。
package sword026;
class Solution {
public Node copyRandomList(Node head) {
if(head==null){
return null;
}
Node now = head;
while(now != null) {
Node newNode = new Node();
newNode.val = now.val;
newNode.next = now.next;
now.next = newNode;
now = newNode.next;
}
now = head;
while(now != null) {
Node next = now.next;
if(now.random != null) {
next.random = now.random.next;
}
now = next.next;
}
Node newHead = head.next;
Node newTail = newHead;
now = head;
while(newTail.next != null) {
now.next = newTail.next;
now = newTail.next;
newTail.next = now.next;
newTail = now.next;
}
now.next = null;
return newHead;
}
}