题目:
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.
解题:
这题是要复制一个链表,这个链表比普通的链表多一个指针,这个指针可以指向任意地方,可以为空也可以为链表中的任一个节点,今天中午的时候我同学和我说起这题,当时问我的解题思路,我想了想给出了基本思路:借助哈希表第一遍遍历的时候创建新的链表这时候不管random指针域,这个留着第二遍的时候进行处理。
晚上的时候我就开始写代码实现,可能是因为这阵子都没有怎么刷题都在看书,发现有点生疏了。我觉得程序员实现自己的想法是一个很重要的能力,最基本的要求是先实现你的想法,实现之后再去考虑优化。习大大说过,空谈误国,实干兴邦。好吧我开始写,写的时候发现问题挺多的,真的是太久没写了。
第一次解的时候我用了哈希表,我现在想想也是醉了,不过后面优化的时候逐渐2个哈希表 1个哈希表。
三种解法思路其实是一样的,只是一开始有很多冗余的地方。
解法1:
public static RandomListNode copyRandomList(RandomListNode head) { //定义哈希表 HashMap<Integer, RandomListNode> hashtable=new HashMap<>();//存random指向的链表节点 HashMap<Integer, RandomListNode> newhashtable=new HashMap<>();//存新的链表节点 HashMap<RandomListNode,Integer> hashtable2=new HashMap<>();//存原有的节点 //返回结果 RandomListNode newHead=head; if(head==null)//空链表 return head; if(head.next==null)//一个节点时 { RandomListNode tNode=new RandomListNode(head.label); if(head.random!=null) tNode.random=tNode; return tNode; } RandomListNode cur=head; //第一遍遍历 建立哈希表 和创建除了random指针为空外的新链表数组 int i=0; while(cur!=null) { hashtable.put(i, cur.random); hashtable2.put(cur,i); RandomListNode tNode=new RandomListNode(cur.label); newhashtable.put(i, tNode); if(i==0) newHead=tNode;//记录新链表的第一个节点 cur=cur.next; i++; } //再次遍历 处理随机指针 int j=0; cur=head; while(cur!=null) { if(j>0) { newhashtable.get(j-1).next=newhashtable.get(j); } if(hashtable2.get(hashtable.get(j))!=null) { int key=hashtable2.get(hashtable.get(j));//随机指针指向第几个 newhashtable.get(j).random=newhashtable.get(key); } else { newhashtable.get(j).random=null; } cur=cur.next; j++; } return newHead; }
public static RandomListNode copyRandomList2(RandomListNode head) { //新建两个哈希表 分别存原来节点和随机指针 原来节点和新建节点(这里要求深度复制 必须是new的才可以) HashMap<RandomListNode, RandomListNode> randomMap=new HashMap<>(); HashMap<RandomListNode, RandomListNode> newMap=new HashMap<>(); //返回结果 RandomListNode fakeNode=new RandomListNode(-1); //进行第一次遍历 将节点存入哈希表 RandomListNode cur=head; RandomListNode pre=fakeNode; while(cur!=null) { randomMap.put(cur, cur.random); RandomListNode newNode=new RandomListNode(cur.label); newMap.put(cur, newNode); cur=cur.next; pre.next=newNode; pre=pre.next; } //对哈希表进行遍历 为需要复制的链表加上随机指针 Iterator<RandomListNode> iterator=randomMap.keySet().iterator(); while(iterator.hasNext()) { RandomListNode node=(RandomListNode) iterator.next(); RandomListNode copyNode=newMap.get(node); RandomListNode randNode=randomMap.get(node); if(randNode!=null) copyNode.random=newMap.get(randNode); else { copyNode.random=null; } } //返回结果 return fakeNode.next; }
public static RandomListNode copyRandomList3(RandomListNode head) { HashMap<RandomListNode, RandomListNode> newMap=new HashMap<>(); //进行第一次遍历 将节点存入哈希表 RandomListNode cur=head; while(cur!=null) { RandomListNode newNode=new RandomListNode(cur.label); newMap.put(cur, newNode); cur=cur.next; } cur=head; while(cur!=null) { RandomListNode node=newMap.get(cur); node.next=newMap.get(cur.next); node.random=newMap.get(cur.random); cur=cur.next; } return newMap.get(head); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
LeetCode138 Copy List with Random Pointer(深度复制带有随机指针的链表) Java题解
原文地址:http://blog.csdn.net/u012249528/article/details/47111467