• Careercup


    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 }
  • 相关阅读:
    base64编码
    ios开发之指纹识别
    date
    php的学习
    mac下安装mysql遇到的无法连接的问题
    关于git上传文件过大报错的问题 remote: warning: Large files detected.
    安卓开发中Theme.AppCompat.Light的解决方法
    ubuntu操作系统中卸载mysql的安装与卸载
    重新格式化删除U盘隐藏分区与如何在LMT下安装非Ghost win7
    网易有道笔试2015-05-12
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3722689.html
Copyright © 2020-2023  润新知