Copy List with Random Pointer
https://leetcode.com/problems/copy-list-with-random-pointer/
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.
解題思路:
啥叫deep copy,啥叫shallow copy?Java里shallow copy的意思是,B拷貝于A,但B和A指向同一個對象。deep copy的意思是,B和A指向不同的對象,但這兩個對象完全一樣。
具體可以參考?http://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java
那么這道題目的難度就在于多了一個random指針。當前節點和next很容易復制,遍歷一遍,不斷根據原來鏈表的值去new新節點,并將next指向下一節點即可。問題是,第二遍的時候,如何找到當前節點的random節點?
這里借用的是HashMap這個數據結構,第一遍遍歷的時候,建立一個map,key是原鏈表的節點,value是當前鏈表的節點。我們知道,實際上map里存的是相應的地址。這樣,第二遍尋找新鏈表當前節點node的random時,只要在map里找原鏈表對應節點的value就可以了。
代碼如下:
/*** Definition for singly-linked list with a random pointer.* class RandomListNode {* int label;* RandomListNode next, random;* RandomListNode(int x) { this.label = x; }* };*/ public class Solution {public RandomListNode copyRandomList(RandomListNode head) {if (head == null) {return head;}Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();RandomListNode copyHead = new RandomListNode(head.label);RandomListNode head1 = head;RandomListNode returnHead = copyHead;map.put(head1, copyHead);while(head1.next != null) {copyHead.next = new RandomListNode(head1.next.label);map.put(head1.next, copyHead.next);copyHead = copyHead.next;head1 = head1.next;}copyHead = returnHead;head1 = head;while(copyHead != null) {copyHead.random = map.get(head1.random);copyHead = copyHead.next;head1 = head1.next;}return returnHead;} }上面的解法應該是比較容易理解的。Google到網友還有另一種比較好的解法,可以只花額外的O(1)空間,使用同樣O(n)的時間。
這么做:
1. 在原來鏈表的每個節點后,插入一個一模一樣的復制節點。這樣copy的next順序就自然出來了。比如1-1'-2-2'-3-3'
2.?將每個復制的節點的random指向它前一個節點的random的下一個節點
3. 按next的順序抽出所有復制的節點,形成新的鏈表并返回。
代碼如下
/*** Definition for singly-linked list with a random pointer.* class RandomListNode {* int label;* RandomListNode next, random;* RandomListNode(int x) { this.label = x; }* };*/ public class Solution {public RandomListNode copyRandomList(RandomListNode head) {if (head == null) {return head;}RandomListNode returnHead = head;//在原鏈表的每個節點后都插入一個新節點while(head != null) {RandomListNode newNode = new RandomListNode(head.label);newNode.next = head.next;head.next = newNode;head = head.next.next;}//將每個復制的節點的random指向它前一個節點的random的nexthead = returnHead;while(head != null) {if(head.random != null) {head.next.random = head.random.next;}head = head.next.next;}//抽出每個復制的節點,返回head = returnHead;returnHead = returnHead.next;while(head != null) {RandomListNode newNode = head.next;head.next = head.next.next;//這個邊界條件一定要注意,否則原鏈表只有一個節點的時候會越界if(newNode.next != null) {newNode.next = newNode.next.next;}head = head.next;}return returnHead;} }可以看出,上面的思想,同樣是要用某種方法在新復制的鏈表里找到每個節點的random節點,方法依然是要依賴于原鏈表。但是思路非常巧妙,值得體會。
轉載于:https://www.cnblogs.com/NickyYe/p/4379237.html
總結
以上是生活随笔為你收集整理的Copy List with Random Pointer的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 廖雪峰Java1-2程序基础-7布尔运算
- 下一篇: LightOJ - 1422 (区间DP