2014-05-12 06:56

题目链接

原题:

A link list contains following elements



struct node{
    int data;
    node* next;
    node* random;
}

Given head of such a linked list write a function who copies such a linked list and returns the head of the new list. So if in the original list first node points to fourth node in random the copy should have the same relation. The random pointer can point to any node including itself and more than two nodes can have random pointer to the same node. 

Required time complexity O(n) and no extra space can be used (apart from the newly allocated memory which you will need to create the new list)

题目:Leetcode上有这题,Copy List with Random Pointer。不过要求做到O(n)时间以及O(1)空间。

解法:之前我用了哈希表,能够实现O(n)时间,但不能做到O(1)空间。查阅了别人的解法后我发现自己的思路果然还不够灵活。这种解法很巧妙,先将新节点按照“旧->新->旧->新->旧->新”穿插到旧链表中,然后执行一条关键语句:ptr->next->random = ptr->random->next。执行完了以后将两条链表拆开即可(归并链表的逆过程)。哎,又是一个需要灵感才能想出的算法。

代码:

  1 // http://www.careercup.com/question?id=5917873302142976
  2 #include <iostream>
  3 #include <unordered_map>
  4 using namespace std;
  5 
  6 struct ListNode {
  7     int val;
  8     ListNode *next;
  9     ListNode*random;
 10     ListNode(int _val = 0): val(_val), next(nullptr), random(nullptr) {};
 11 };
 12 
 13 class Solution {
 14 public:
 15     ListNode *copyListWithRandomPointer(ListNode *head) {
 16         if (head == nullptr) {
 17             return nullptr;
 18         }
 19         ListNode *new_head;
 20         ListNode *p1, *p2;
 21         
 22         p1 = head;
 23         while (p1 != nullptr) {
 24             p2 = new ListNode(p1->val);
 25             p2->next = p1->next;
 26             p1->next = p2;
 27             p1 = p1->next->next;
 28         }
 29         
 30         p1 = head;
 31         while (p1 != nullptr) {
 32             p1->next->random = p1->random == nullptr ? nullptr : p1->random->next;
 33             p1 = p1->next->next;
 34         }
 35         new_head = splitList(head);
 36         
 37         return new_head;
 38     };
 39 private:
 40     ListNode *splitList(ListNode *head) {
 41         ListNode *head1, *head2;
 42         ListNode *ptr1, *ptr2;
 43         
 44         // head1 is the original list.
 45         head1 = ptr1 = nullptr;
 46         // head2 is the new list.
 47         head2 = ptr2 = nullptr;
 48         while (true) {
 49             if (head == nullptr) {
 50                 break;
 51             }
 52             if (head1 == nullptr) {
 53                 head1 = ptr1 = head;
 54             } else {
 55                 ptr1->next = head;
 56                 ptr1 = ptr1->next;
 57             }
 58             head = head->next;
 59             
 60             if (head == nullptr) {
 61                 break;
 62             }
 63             if (head2 == nullptr) {
 64                 head2 = ptr2 = head;
 65             } else {
 66                 ptr2->next = head;
 67                 ptr2 = ptr2->next;
 68             }
 69             head = head->next;
 70         }
 71         
 72         return head2;
 73     };
 74 };
 75 
 76 void deleteList(ListNode *&head)
 77 {
 78     ListNode *ptr;
 79     
 80     ptr = head;
 81     while (head != ptr) {
 82         ptr = head;
 83         head = head->next;
 84         delete ptr;
 85     }
 86 }
 87 
 88 int main()
 89 {
 90     int val;
 91     int n;
 92     int i;
 93     ListNode *head1, *head2;
 94     ListNode *ptr;
 95     unordered_map<int, ListNode *> um;
 96     Solution sol;
 97     
 98     while (cin >> n && n > 0) {
 99         head1 = head2 = nullptr;
100         for (i = 0; i < n; ++i) {
101             cin >> val;
102             if (head1 == nullptr) {
103                 head1 = ptr = new ListNode(val);
104             } else {
105                 ptr->next = new ListNode(val);
106                 ptr = ptr->next;
107             }
108             um[i] = ptr;
109         }
110         
111         ptr = head1;
112         for (i = 0; i < n; ++i) {
113             cin >> val;
114             if (val >= 0) {
115                 ptr->random = um[val];
116             } else {
117                 ptr->random = nullptr;
118             }
119             ptr = ptr->next;
120         }
121         
122         head2 = sol.copyListWithRandomPointer(head1);
123         ptr = head2;
124         while (ptr != nullptr) {
125             cout << ptr->val << ' ';
126             cout << (ptr->random != nullptr ? ptr->random->val : -1) << endl;
127             ptr = ptr->next;
128         }
129         
130         deleteList(head1);
131         deleteList(head2);
132     }
133     
134     return 0;
135 }

 

 posted on 2014-05-12 07:08  zhuli19901106  阅读(213)  评论(0编辑  收藏  举报