剑指offer—35.复杂链表的复制—分析及代码(Java)

剑指offer——35.复杂链表的复制——分析及代码[Java]

  • 一、题目
  • 二、分析及代码
    • 1. 借助原链表复制
      • (1)思路
      • (2)代码
      • (3)结果
  • 三、其他

一、题目

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

二、分析及代码

1. 借助原链表复制

(1)思路

本题总体上有两种思路:
1)直接重建一个链表,先复制 next 指针,再复制 random 指针。由于链表本身的特性,无法直接找到对应位置的指针,可通过建立哈希表的方法,以空间换时间,将查找位置的时间复杂度降到 O(1);
2)借助原链表进行复制,这一方法在保持 O(n) 时间复杂度的同时,无需增加额外的存储空间,下面主要介绍该方法。

借助原链表进行复制,可大致分为三步:
1)在原链表中的每个节点后,添加对应复制的新节点;
2)依次复制各节点的随机指针,借助原链表的位置关系,可直接获取新链表的指向对象;
3)将得到的链表拆分成各自独立的新、老链表。

(2)代码

public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
        if (pHead == null)
            return null;
        
        // 在原链表中每个节点后添加新节点
        RandomListNode node = pHead;
        while (node != null) {
            RandomListNode newNode = new RandomListNode(node.label);
            newNode.next = node.next;
            node.next = newNode;
            node = newNode.next;
        }
        
        // 复制随机指针
        node = pHead;
        while (node != null) {
            if (node.random != null)
                node.next.random = node.random.next;
            node = node.next.next;
        }
        
        // 拆分新老链表
        node = pHead;
        RandomListNode newRoot = pHead.next;
        while (node != null) {
            RandomListNode newNode = node.next;
            node.next = newNode.next;
            newNode.next = newNode.next == null? null : newNode.next.next;
            node = node.next;
        }
        
        return newRoot;
    }
}

(3)结果

运行时间:21ms,占用内存:9652k。

三、其他

暂无。

你可能感兴趣的:(数据结构与算法)