[LeetCode]138复制带随机指针的链表
题目描述:
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的深度拷贝。
思路:
先遍历链表,将每个节点对应的随机指针指向的对象利用HashMap存起来,key的值就为节点的在链表里面的位置,Value的值是随机指针指向的对象
再把原链表的节点对应的在链表中的位置存起来,key为节点对象,然后将节点的label取出来新建节点,存起来
再次遍历链表,处理随机指针
这是第一种用HashMap的办法,但是性能不行,还有优化的空间,之后我再研究研究看能不能改改
public static RandomListNode copyRandomList(RandomListNode head) { HashMap<Integer,RandomListNode> randomMap = new HashMap<>();//随机节点 HashMap<Integer,RandomListNode> newMap = new HashMap<>();//新的节点 HashMap<RandomListNode,Integer> oldMap = new HashMap<>();//原表的节点 RandomListNode result = head; if(head==null) return head; if(head.next==null){ RandomListNode it = new RandomListNode(head.label); if (head.random!=null){ it.random = it;//指向自己 } return it; } //迭代 RandomListNode iterator = head; int i = 0; while(iterator!=null){ //将第几位对应的随机指针存起来 randomMap.put(i,iterator.random); //原链表节点对应的位置存起来 oldMap.put(iterator,i); //新建节点,复制 RandomListNode node = new RandomListNode(iterator.label); newMap.put(i,node); if(i==0){ //第一个 result = node; } iterator = iterator.next; i++; } i = 0; iterator = head; while(iterator!=null){ if(i>0) newMap.get(i-1).next = newMap.get(i); //检测原节点的随机指针是否为空 if(oldMap.get(randomMap.get(i))!=null){ //获得原链表节点的随机指针指向的对象的位置 int random = oldMap.get(randomMap.get(i)); //赋值 newMap.get(i).random = newMap.get(random); }else { //随机指针为空的情况 newMap.get(i).random = null; } iterator = iterator.next; i++; } return result; } static class RandomListNode { int label; RandomListNode next, random; RandomListNode(int x) { this.label = x; } }
第二种办法,先将节点复制,插入到被复制的节点的后面,然后将随机节点加入进去,之后拆分链表
import java.util.*; public class Solution { public RandomListNode Clone(RandomListNode pHead) { if (pHead==null) return null; RandomListNode current = pHead; //将复制的节点插入 while (current!=null){ RandomListNode clone = new RandomListNode(current.label); RandomListNode next = current.next; current.next = clone; clone.next = next; current = next; } //将随机节点加入 current = pHead; while (current!=null){ current.next.random = current.random==null?null:current.random.next;//指向新的随机节点 current = current.next.next; } //拆分 current = pHead; RandomListNode res = pHead.next; while (current!=null){ RandomListNode clone = current.next; current.next = clone.next; clone.next = clone.next==null?null:clone.next.next; current = current.next; } return res; }