复制一个带随机指针的链表

阿里巴巴测试开发校招二面的一个面试题
一个单链表除了next指针外,还带有一个随机指针(设为rand)指向任意元素,用最少的时间复杂度和最少的空间复制该链表。

开始想了很久,只想到一个O(n^2)的方法,显然没能令面试官满意,面试官也没有告诉我正确的方法,只是对我的思路表示肯定。下面先介绍一个我的面试的时候想到的方法。

方法1:
将这个链表看成是一个图,一个有向的图,用一个二维的数组来记录这个图的每个节点的指向。然后根据这个数组来建立相应的图。由于需要知道每个节点的随机节点的指向,故需要遍历整个链表。所以n个节点,所以时间复杂度就是O(n^2)了。
回到宿舍后,和几个朋友一番讨论,想到一个O(n)的方法。


方法2:

可以用O(n)的时间复杂度和O(1)的附加空间实现:根据源链表依次复制出新链表的对应节点,并将新节点插入到源节点后,新链表的rand指针指向原链表的rand;然后遍历一遍链表,将新链表的rand指针指向对应元素的next元素(即新链表中对应的rand指针元素);最后将新链表和源链表分离。

struct node_t {
    int data;
    struct node_t *next;
    struct node_t *rand;
};


struct node_t * copylist(struct node_t **dest, struct node_t *src) {
    struct node_t *p, *q;
    p = src;

    /* 在原节点后插入一个新的节点,原节点的next指针指向新节点,新节点的随机指针指向原节点的随机指针的节点 */
    while (p != NULL) {
        q = (struct node_t *)malloc(sizeof(struct node_t));
        q->data = p->data;
        q->next = p->next; q->rand = p->rand;
        p->next = q;
        p = q->next;
    }

   /* 处理新的节点,新节点的随机指针指向原节点下随机指针的下一个节点 */
   p = src; 
   while (p != NULL) { 
      q = p->next; 
      q->rand = q->rand->next; 
      p = q->next; 
   } 

   p = src; 
   *dest = p->next;
    /* 将原节点和新节点分离,恢复原节点 */
   while (p != NULL) { 
      q = p->next; 
      p->next = q->next; 
      p = p->next;
      if (p != NULL) 
         q->next = p->next; 
   } 
   return *dest;
}



方法2是改变next指针,也可以考虑改变随机指针,思路是一样的。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值