这个刚开始想的是先顺着next遍历一遍链表,把所有元素都存在动态数组里。然后再遍历各个结点的random,把random都连上。
但提交后发现,next有可能无法遍历完所有的结点,比如有的结点的random连接的是并没有在next链中出现的结点。
1->2->3->4->null 5->6
如果1的random是5,那光靠next是遍历不到的。
同理,先遍历random也会丢失元素。
怎么先遍历完所有元素?纠结了我半天。然后突然想明白了:其实,不管是next,还是random,只是名字不同而已,他们只是代表了两条从pHead开始的链表。你先遍历next,那random是跳着连的;但你要先遍历random,其实random是连续的,next是跳着的。
所以,这就是个简单的路径选择问题,或者说,二叉树的左右树。只不过遍历的中途可能遍历到已经遍历过的结点,那做个标记就行了。
标记flag用int,0代表第一次来,啥没做过;1代表next已经遍历过了;2代表next,random都遍历过了,结束吧!
既然是二叉树,自然是用递归。代码如下:

import java.util.*;
public class Solution {   
    public static ArrayList<RandomListNode> alrs1;   //原始节点队列
    public static ArrayList<RandomListNode> alrs2;   //复制节点队列
    public static ArrayList<Integer> flag;           //路径选择标志

    public RandomListNode Clone(RandomListNode pHead)
    {
        if(pHead==null){
            return pHead;
        }
        alrs1=new ArrayList<RandomListNode>();
        alrs2=new ArrayList<RandomListNode>();
        flag=new ArrayList<Integer>();

        alrs1.add(pHead);
        RandomListNode p=new RandomListNode(pHead.label);
        RandomListNode first=p;
        alrs2.add(p);
        flag.add(1);
        bianli(pHead.next,p);
        if(flag.get(0)==1){
            bianli(pHead.random,p);
        }        
        return first;
    }

    public void bianli(RandomListNode rn,RandomListNode pre){
        if(rn==null){
            return;
        }
        int loc=alrs1.indexOf(rn);
        RandomListNode buf;
        if(loc==-1){
            alrs1.add(rn);
            buf=new RandomListNode(rn.label);
            alrs2.add(buf);
            int loc2=alrs2.indexOf(pre);
            if(flag.get(loc2)==2) {
        pre.random=buf;
        }else {
        pre.next=buf;
        }
            pre=buf;
            flag.add(0);
            loc=flag.size()-1;
        }else{
            buf=alrs2.get(loc);
            pre.random=buf;
            pre=buf;
        }
        if(flag.get(loc)==0){
            flag.set(loc,1);
            bianli(rn.next,buf);
            if(flag.get(loc)==1){
                bianli(rn.random,buf);
            }            
        }else if(flag.get(loc)==1){
            flag.set(loc,2);
            bianli(rn.random,buf);
        }else{
            return;
        }
    }
}