码迷,mamicode.com
首页 > 编程语言 > 详细

LeetCode138 Copy List with Random Pointer(深度复制带有随机指针的链表) Java题解

时间:2015-07-28 23:17:43      阅读:583      评论:0      收藏:0      [点我收藏+]

标签:链表复制   leetcode   java   

题目:

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;
		 
		 
	        
	    }

解法2:

 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;
		 
		 
		 
		 

	 }

解法3:

 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题解

标签:链表复制   leetcode   java   

原文地址:http://blog.csdn.net/u012249528/article/details/47111467

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!