138 複雜連結串列的深度拷貝 copy list with random pointer
阿新 • • 發佈:2018-11-12
問題分析:
一個複雜的連結串列,節點中有一個指向本連結串列任意某個節點的隨機指標(也可能為空),求這個連結串列的深度拷貝
思路:
此題有兩種方法,一種是按照原連結串列next的順序依次建立節點,並處理好新連結串列的next指標,同時把原節點與新節點的對應關係儲存到一個hash_map中,然後第二次迴圈將random指標處理好。這種方法的時間複雜度是O(n),空間複雜度也是O(n)。
第二種方法則是在原連結串列的每個節點之後插入一個新的節點,這樣原節點與新節點的對應關係就已經明確了,因此不需要用hash_map儲存,但是需要第三次迴圈將整個連結串列拆分成兩個。這種方法的時間複雜度是O(n),空間複雜度是O(1)。
但是利用hash_map的方法具有其他的優點,如果在迴圈中加入一個判斷,就可以檢測出連結串列中是否有迴圈;而第二種方法則不行,會陷入死迴圈。
/** * 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) { HashMap<RandomListNode,RandomListNode> map=new HashMap<>(); RandomListNode cur=head; //第一步,將結點存入雜湊表 while(cur!=null){ RandomListNode newNode=new RandomListNode(cur.label); map.put(cur,newNode); cur=cur.next; } // cur=head; while(cur!=null){ RandomListNode node=map.get(cur); node.next=map.get(cur.next); node.random=map.get(cur.random); cur=cur.next; } return map.get(head); } }
方法二:c++
/** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; * RandomListNode *next, *random; * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} * }; */ class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { if(head==NULL){ return NULL; } RandomListNode *now = head; //複製各個節點 while(now){ RandomListNode *copy = new RandomListNode(now->label); copy->next = now->next; now->next = copy; now = copy->next; } for(now=head; now; now=now->next->next){ //複製random指標域 now->next->random = (now->random)?now->random->next:NULL; } RandomListNode* h = head->next; //斷開成兩個連結串列 RandomListNode* t = h; RandomListNode* tail = head; for(;;){ tail->next = t->next; tail = tail->next; if(tail==NULL){ break; } t->next = tail->next; t = t->next; } return h; } };