/**138. Copy List with Random Pointer * @param head * @return 深度複製一個鏈表,使用重新分配記憶體儲存新的 */ public RandomListNode copyRandomList(RandomListNode head) { if (head == null || head.next == null) { return head; } Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>(); RandomListNode ret = new RandomListNode(head.label); map.put(head, ret); RandomListNode rhead = ret; RandomListNode phead = head; while (head != null) { RandomListNode node = new RandomListNode(head.label); map.put(head, node); ret.next = node; ret = ret.next; head = head.next; } ret = rhead; head = phead; while(head != null) { ret.random = map.get(head.random); ret = ret.next; head = head.next; } return rhead; }
/*HashMap的key存原始pointer,value存新的pointer。第一遍,先不copy random的值,只copy數值建立好新的鏈表。並把新舊pointer存在HashMap中。第二遍,遍曆舊錶,複製random的值,因為第一遍已經把鏈表複製好了並且也存在HashMap裡了,所以只需從HashMap中,把當前舊的node.random作為key值,得到新的value的值,並把其賦給新node.random就好。 * */
public RandomListNode copyRandomList1(RandomListNode head) { if (head == null) return head; /*第一步:在OldList的每個節點後面都插入一個copyNode(拷貝鏈表的結點)*/ RandomListNode nowNode = head; while (nowNode != null){ RandomListNode copyNode = new RandomListNode(nowNode.label); copyNode.random = nowNode.random; copyNode.next = nowNode.next; nowNode.next = copyNode; nowNode = nowNode.next.next; } /*第二步:確定NewList的每個節點,真正關聯到的Random結點是哪個, * 因為第一步已經把所有NewList上的結點都建立了*/ nowNode = head; while (nowNode != null){ if (nowNode.random != null){ nowNode.next.random = nowNode.random.next; } nowNode = nowNode.next.next; } /*第三步:還原OldList的next為一開始的next結點 * 並拼接NewList的next到它真正所應該關聯的next結點 * 即:保持老鏈表OldList不變,拼接新鏈表NewList。 * */ RandomListNode pHead = new RandomListNode(0); pHead.next = head; RandomListNode newlist = pHead; nowNode = head; while (nowNode != null){ pHead.next = nowNode.next; nowNode.next = pHead.next.next; pHead = pHead.next; nowNode = nowNode.next; } return newlist.next; }