Careercup - Microsoft面试题 - 5917873302142976

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 }

 

转载于:https://www.cnblogs.com/zhuli19901106/p/3722689.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值