zoukankan      html  css  js  c++  java
  • 剑指Offer

    剑指Offer - 九度1524 - 复杂链表的复制
    2014-02-07 01:30
    题目描述:

    输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。

    输入:

    输入可能包含多个测试样例,输入以EOF结束。
    对于每个测试案例,输入的第一行为一个整数n (1<=n<=1000):n代表将要输入的链表元素的个数。(节点编号从1开始)。
    接下来有n个数,表示链表节点中的值。
    接下来有n个数Ti,Ti表示第i个节点的另一个指针指向。
    Ti = 0 表示这个指针为NULL。

    输出:

    对应每个测试案例,
    输出n行,每行有二个数,第一个代表当前节点值,第二个代表当前节点的特殊指针的值。

    样例输入:
    5
    1 2 3 4 5
    3 5 0 2 0
    样例输出:
    1 3
    2 5
    3 0
    4 2
    5 0
    题意分析:
      对于一个含有n个节点的单向链表,指针域中除了next之外,还有一个指向另一个节点或者指向NULL的随机指针。本题的任务是复制一份这样的链表出来。
      我的思路,当然是先给节点编号,然后根据编号对应关系重建链表。
      其中重要的一步,就是将这些链表节点和1~n的n个整数一一映射起来。这样一来,就能方便地表示随机指针中到底是谁指向谁了。
      因为使用了map,所以映射的过程时间复杂度为O(n * log(n))。复制新链表时,也需要查反向映射,仍需要O(n * log(n))的时间。
      如果使用适当的hash策略,可以做到接近O(1)的映射时间,时间复杂度也可以降到O(n),但需要额外编码就是了。空间复杂度为O(n)。
      最后,不要偷懒直接用数组AC掉(^_^),AC的目的在于学会,而不是通过。
      1 // 688806    zhuli19901106    1524    Accepted    点击此处查看所有case的执行结果    1160KB    3820B    50MS
      2 // 201402012144
      3 #include <cstdio>
      4 #include <map>
      5 using namespace std;
      6 
      7 struct RandomListNode {
      8     int label;
      9     RandomListNode *next, *random;
     10     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
     11 };
     12 
     13 // This code segment is copied from my leetcode problem set.
     14 class Solution {
     15 public:
     16     RandomListNode *copyRandomList(RandomListNode *head) {
     17         int n;
     18         
     19         if(NULL == head){
     20             return NULL;
     21         }
     22         
     23         n = 0;
     24         RandomListNode *ptr;
     25         
     26         mri.clear();
     27         mir.clear();
     28         
     29         ptr = head;
     30         while(ptr != NULL){
     31             ++n;
     32             mri[ptr] = n;
     33             ptr = ptr->next;
     34         }
     35         
     36         RandomListNode *root = new RandomListNode(0), *tail;
     37         ptr = head;
     38         int i = 0;
     39         tail = root;
     40         while(ptr != NULL){
     41             ++i;
     42             tail->next = new RandomListNode(ptr->label);
     43             tail = tail->next;
     44             mir[i] = tail;
     45             ptr = ptr->next;
     46         }
     47         
     48         RandomListNode *p1, *p2;
     49         
     50         p1 = head;
     51         p2 = root->next;
     52         while(p1 != NULL){
     53             if(p1->random != NULL){
     54                 p2->random = mir[mri[p1->random]];
     55             }
     56             p1 = p1->next;
     57             p2 = p2->next;
     58         }
     59         
     60         head = root->next;
     61         delete root;
     62         mir.clear();
     63         mri.clear();
     64         
     65         return head;
     66     }
     67 
     68     RandomListNode *deleteList(RandomListNode *head) {
     69         RandomListNode *ptr1, *ptr2;
     70 
     71         if (NULL == head) {
     72             return NULL;
     73         }
     74 
     75         ptr1 = head;
     76         while (ptr1 != NULL) {
     77             ptr2 = ptr1->next;
     78             delete ptr1;
     79             ptr1 = ptr2;
     80         }
     81 
     82         return NULL;
     83     }
     84 private:
     85     map<RandomListNode *, int> mri;
     86     map<int, RandomListNode *> mir;
     87 };
     88 
     89 int main()
     90 {
     91     map<RandomListNode *, int> mri;
     92     map<int, RandomListNode *> mir;
     93     int n, i;
     94     int label;
     95     RandomListNode *head1, *head2, *tail, *ptr;
     96     Solution solution;
     97 
     98     while (scanf("%d", &n) == 1) {
     99         mri.clear();
    100         mir.clear();
    101         head1 = head2 = tail = NULL;
    102         for (i = 1; i <= n; ++i) {
    103             scanf("%d", &label);
    104             if (tail == NULL) {
    105                 head1 = tail = new RandomListNode(label);
    106             } else {
    107                 tail->next = new RandomListNode(label);
    108                 tail = tail->next;
    109             }
    110             mri[tail] = i;
    111             mir[i] = tail;
    112         }
    113 
    114         for (i = 1; i <= n; ++i) {
    115             scanf("%d", &label);
    116             if (label > 0) {
    117                 ptr = mir[i];
    118                 ptr->random = mir[label];
    119             }
    120         }
    121 
    122         head2 = solution.copyRandomList(head1);
    123         ptr = head2;
    124         while (ptr != NULL) {
    125             printf("%d ", ptr->label);
    126             if (ptr->random != NULL) {
    127                 printf("%d
    ", ptr->random->label);
    128             } else {
    129                 printf("0
    ");
    130             }
    131             ptr = ptr->next;
    132         }
    133 
    134         head1 = solution.deleteList(head1);
    135         head2 = solution.deleteList(head2);
    136     }
    137 
    138     return 0;
    139 }
    140 /*
    141 // 688773    zhuli19901106    1524    Accepted    点击此处查看所有case的执行结果    1024KB    544B    40MS
    142 // 201402012022
    143 #include <cstdio>
    144 #include <vector>
    145 using namespace std;
    146 
    147 int main()
    148 {
    149     vector<int> va, vb;
    150     int n, i;
    151     int a, b;
    152 
    153     while (scanf("%d", &n) == 1) {
    154         va.clear();
    155         vb.clear();
    156         va.push_back(0);
    157         vb.push_back(0);
    158         for (i = 1; i <= n; ++i) {
    159             scanf("%d", &a);
    160             va.push_back(a);
    161         }
    162         for (i = 1; i <= n; ++i) {
    163             scanf("%d", &b);
    164             vb.push_back(b);
    165         }
    166         for (i = 1; i <= n; ++i) {
    167             printf("%d %d
    ", va[i], va[vb[i]]);
    168         }
    169     }
    170 
    171     return 0;
    172 }
    173 */
  • 相关阅读:
    confluence的安装、破解和汉化
    Linux学习经验集锦
    MFS 分布式文件系统
    MFS
    Docker 搭建 WordPress
    ansible入门
    docker搭建pxc集群与haproxy负载均衡
    mysql-proxy 实现读写分离
    Linux内核学习总结
    lab8:理解进程调度时机跟踪分析进程调度与进程切换的过程
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3539132.html
Copyright © 2011-2022 走看看