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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)