请实现函数ComplexListNode* Clone(ComplexListNode * pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任意结点或者NULL。结点的C++定义如下:

struct ComplexListNode{
    int m_nValue;
    ComplexListNode* m_pNext;
    ComplexListNode* m_pSibling;
};

上图是一个含有5个结点的复杂链表。图中实线箭头表示m_pNext指针,虚线箭头表示m_pSibling指针。为了简单起见,指向NULL的指针没有画出。
思路:

第一步制原始链表上的每个结点N创建N',然后把这些创建出来的结点用m_pNext链接起来。同时我们把<N, N'>的配对信息放到一个哈希表中。第二步还是设置复制链表上的每个结点的m_pSibling。如果在原始链表中结点N的m_pSibling指向结点S,那么在复制链表中,对应的N'应该指向S'。由于有了哈希表,我们可以在O(1)的时间根据S找到S’。这种是以O(n)的空间换来了O(n)的时间复杂度。

代码:

package offer;

import java.util.HashMap;
import java.util.Map;

class ComplexList
{
    char val;
    ComplexList next = null;
    ComplexList extend = null;
    ComplexList(char val)
    {
        this.val = val;
    }
}
public class ti35 {
    static ComplexList CloneComplexList(ComplexList head)
    {
        Map<ComplexList,ComplexList> map = new HashMap<ComplexList,ComplexList>();
        ComplexList CloneNode = new ComplexList('a');
        if(head!=null)
        {
            CloneNode = head;
            map.put(head,CloneNode);
        }
        ComplexList CloneHead = CloneNode;
        while(head.next!=null)
        {
            head = head.next;
            CloneNode = CloneNode.next;
            map.put(head, CloneNode);
        }
        CloneNode = CloneHead;
        while(CloneNode.next!=null)
        {
            CloneNode.extend = map.get(CloneNode.extend);
            CloneNode = CloneNode.next;
        }
        return CloneHead;
    }
    public static void main(String[] args)
    {
        ComplexList a = new ComplexList('A');
        ComplexList b = new ComplexList('B');
        ComplexList c = new ComplexList('C');
        ComplexList d = new ComplexList('D');
        ComplexList e = new ComplexList('E');
        a.next = b;
        b.next = c;
        c.next = d;
        d.next = e;
        b.extend = e;
        a.extend = c;
        d.extend = b;
        ComplexList result = CloneComplexList(a);
        while(result.next!=null)
        {
            System.out.print(result.val+" "+result.next.val+" ");
            if(result.extend!=null)
            {
                System.out.println(result.extend.val);
            }
            else
            {
                System.out.println();
            }
            result = result.next;
        }
    }
}
不使用辅助空间

代码:

static ComplexList CloneComplexList2(ComplexList head)
    {
        if(head==null)
        {
            return head;
        }
        ComplexList p = head;//记录原来链表的头结点
        while(head.next!=null)
        {
            ComplexList x = new ComplexList(head.val);
            x.next = head.next;
            head.next = x;
            head = x.next;
        }
        ComplexList x = new ComplexList(head.val);
        head.next = x;
        head = p;
        while(head.next.next!=null)
        {
            if(head.extend!=null)
            head.next.extend = head.extend.next;
            head = head.next.next;
            
        }
        head = p;
        ComplexList q = head.next,result;//记录克隆链表的头结点
        result = q;
        //System.out.println(q.val+" "+q.next.val);
        while(q.next!=null&&q.next.next!=null)
        {
            //System.out.println(q.val+" "+q.next.val);
            q.next = q.next.next;
            q = q.next;
        }
        return result;
    }

【剑指offer】面试题35:复杂链表的复制(Java 实现)相关推荐

  1. 剑指offer面试题35. 复杂链表的复制(DFS)(深拷贝)

    题目描述 请实现 copyRandomList 函数,复制一个复杂链表.在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null. ...

  2. 剑指offer面试题26-复杂链表的复制

    题目: 请实现函数ComplexListNode* Clone(ComplexListNode* pHead).复制一个复杂链表. 在复杂链表中.每个节点除了一个m_pNext指针指向下一个节点外,另 ...

  3. 剑指offer面试题[26]-复杂链表的复制

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  4. 剑指offer——面试题56:链表中环的入口

    剑指offer--面试题56:链表中环的入口 Solution1: 非常经典的快慢指针套路题.下面这个链接讲解的很详细.其实问题的关键在于为什么快指针的速度一定是慢指针的2倍,3倍或4倍行不行?? 快 ...

  5. 剑指offer——面试题35:第一个只出现一次的字符

    剑指offer--面试题35:第一个只出现一次的字符 Solution1: 垃圾算法不看也罢!自己想到的垃圾算法 class Solution { public:int FirstNotRepeati ...

  6. [剑指offer]面试题35:第一个只出现一次的字符

    面试题35:第一个只出现一次的字符 题目:在字符串中找出第一个只出现一次的字符.如输入"abaccdeff",则输出'b'. 代码如下: char FirstNotRepeatin ...

  7. [剑指offer]面试题15:链表中倒数第k个结点

    面试题15:链表中倒数第k个结点 题目:输入一个链表,输出该链表中倒数第 k 个结点.为了符合大多数人的习惯,本题从1 开始计数,即链表的尾结点是倒数第1 个结点.例如一个链表有6个结点,从头结点开始 ...

  8. 剑指offer面试题15:链表中倒数第K个节点

    题目:输入一个链表,输出该链表的倒数第K个节点.为了符合大多数人的习惯,本题从1开始计数,即链表尾节点是倒数第一个节点. 解题思路: 解法一:一般情况下,单向链表无法从后一个节点获取到它前面的节点,可 ...

  9. 剑指Offer - 面试题24. 反转链表(遍历/递归)

    1. 题目 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4-&g ...

  10. 剑指Offer - 面试题18. 删除链表的节点

    1. 题目 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 注意:此题对比原题有改动 示例 1: 输入: head = [4,5,1,9], val ...

最新文章

  1. pytorch之深入理解collate_fn
  2. NOIP2013pj车站分级[拓扑排序]
  3. 风靡硅谷营销界的 MarTech 魔术
  4. 排序算法的时间复杂度_算法的时间复杂度
  5. linux(2):linux命令查看开放哪些端口
  6. PaperNotes(8)-Stein Variational Gradient Descent A General Purpose Bayesian Inference Algorithm
  7. Linux 系统管理
  8. web测试常用的用例及知识
  9. AndroidStudio_安卓原生开发_自定义服务器Token验证_MD5加密方法---Android原生开发工作笔记156
  10. Windows中使用包管理器(类似于apt/yum的) - Chocolatey
  11. Python3 - 文件处理
  12. Ubuntu 20.04 LTS 修改IP地址
  13. iredMail安装
  14. python模拟登录中国海洋大学教务系统(青果)- 爬取学期所有专业课至excel - 并进行课表排课(一)
  15. 计算机摇号分析,北京市小客车指标管理信息系统
  16. mysql 1062_mysql #1062 报错
  17. C语言项目(四)——基于Linux系统下的带有GUI界面的即时通信软件
  18. win7设置桌面豆绿色
  19. AutoStitch: a new dimension in automatic image stitching
  20. 去中心化金融的无常损失

热门文章

  1. 计算机等级考试试题在线测试,计算机等级考试上机练习题.pdf
  2. laravel 判断字符串包含_laravel 字符串操作大全
  3. Google | 突破瓶颈,打造更强大的Transformer
  4. Java多线程系列(八):ConcurrentHashMap的实现原理(JDK1.7和JDK1.8)
  5. 论文浅尝 - AAAI2020 | 多轮对话系统中的历史自适应知识融合机制
  6. 论文浅尝 | SenticNet 5: 借助上下文嵌入信息为情感分析发现概念级别的原语
  7. 论文浅尝 | How to Keep a Knowledge Base Synchronized
  8. 关于PaddleNLP如何加载训练好的模型进行NER
  9. 数字孪生及其在航空航天中的应用
  10. (附源码gitHub下载地址)spring boot -jta-atomikos分布式事务