[剑指offer] 25. 复杂链表的复制

题目描述

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


思路:

因为新链表也需要复制旧链表的random指针,而random指向的节点也有其next和random,需要保持链表的连贯,所以需要考虑先做出一条新链表,再去构建每一个节点的random节点,而如何同步random节点就是问题所在。有两种解决办法。

解法一:构建同一链表后拆分

1.新旧链表构建在一起,形成Z字型

2.为每一个新节点同步random节点

3.分开两个链表

class Solution
{
public:
  RandomListNode *Clone(RandomListNode *pHead)
  {
    if (pHead == NULL)
      return NULL;
    RandomListNode *newHead = new RandomListNode(pHead->label);
    RandomListNode *curNode1 = pHead;
    RandomListNode *curNode2 = newHead;
    // 新旧链表形成Z链
    while (curNode1)
    {
      curNode2->next = curNode1->next;
      curNode1->next = curNode2;

      curNode1 = curNode2->next;
      curNode2 = curNode1 == NULL ? NULL : new RandomListNode(curNode1->label);
    }

    curNode1 = pHead;
    curNode2 = newHead;
    // 新链添加random
    while (curNode1)
    {
      curNode2->random = curNode1->random == NULL ? NULL : curNode1->random->next;
      curNode1 = curNode2->next;
      curNode2 = curNode1 == NULL ? NULL : curNode1->next;
    }

    curNode1 = pHead;
    curNode2 = newHead;
    // 脱链
    while (curNode1)
    {
      curNode1->next = curNode2->next;
      curNode2->next = curNode1->next == NULL ? NULL : curNode1->next->next;

      curNode1 = curNode1->next;
      curNode2 = curNode2->next;
    }
    return newHead;
  }
};

解法二:利用哈希表

先构建新链表(label,next),同时哈希表存储(旧链表节点,新链表节点)映射关系

再遍历一遍旧链表,利用哈希的映射为新链表random赋值,oldNode->random = hash[newNode->random]

class Solution
{
public:
  RandomListNode *Clone(RandomListNode *pHead)
  {
    if (pHead == NULL)
      return NULL;

    map<RandomListNode *, RandomListNode *> m;
    RandomListNode *curNode1 = pHead;
    RandomListNode *curNode2 = new RandomListNode(curNode1->label);
    RandomListNode *newHead = curNode2;
    m[curNode1] = curNode2;
    while (curNode1)
    {
      curNode2->next = curNode1->next == NULL ? NULL : new RandomListNode(curNode1->next->label);
      curNode1 = curNode1->next;
      curNode2 = curNode2->next;
      m[curNode1] = curNode2;
    }

    curNode1 = pHead;
    curNode2 = newHead;
    while (curNode1)
    {
      curNode2->random = m[curNode1->random];
      curNode1 = curNode1->next;
      curNode2 = curNode2->next;
    }
    return newHead;
  }
};

原文地址:https://www.cnblogs.com/ruoh3kou/p/10075817.html

时间: 2024-08-01 12:15:22

[剑指offer] 25. 复杂链表的复制的相关文章

【剑指offer】复杂链表的复制

转载请注明出处:http://blog.csdn.net/ns_code/article/details/26154691 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点). 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n (1<=n<=1000):n代表将要输入的链表元素的个数.(节点编号从1开始).接下来有n个数,表示链表节点中的值.接下来有n个数Ti,Ti表示第i个节点的另

剑指offer (27) 复杂链表的复制

题目:请实现一个函数,复制一个复杂链表,在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点,还有一个m_pSibling指向链表中的任意节点或者NULL struct ComplexListNode { int m_nValue; ComplexListNode* m_pNext; ComplexListNode* m_pSibling; }; 方法一: step1. 复制原始链表的每一个节点,并用m_pNext链接起来 step2. 设置每个结点的m_pSibling指针 由于m

【Java】 剑指offer(35) 复杂链表的复制

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表.在复杂链表中,每个结点除了有一个m_pNext指针指向下一个点外,还有一个m_pSibling 指向链表中的任意结点或者nullptr. 思路 思路1:先复制结点,用next链接,最后根据原始结点的sibling指针确定该sibling结点距离头结点的位

《剑指offer》复杂链表的复制

[ 声明:版权所有,转载请标明出处,请勿用于商业用途.  联系信箱:[email protected]] 题目链接:http://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向

剑指offer:复杂链表的复制

题目描述输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) # -*- coding: utf-8 -*- # @Time : 2019-07-05 15:52 # @Author : Jayce Wong # @ProjectName : job # @FileName : complexListNodeClone.py # @Bl

剑指offer 25. 分解让复杂问题简单 复杂链表的复制

题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) 解题思路 package jianzhioffer.linkedlist; import com.sun.org.apache.xalan.internal.xsltc.dom.ClonedNodeListIterator; /** * @author hadoop */

剑指OFFER之反转链表(九度OJ1518)

题目描述: 输入一个链表,反转链表后,输出链表的所有元素.(hint : 请务必使用链表) 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000):代表将要输入的链表的个数.输入的第二行包含n个整数t(0<=t<=1000000):代表链表元素. 输出: 对应每个测试案例,以此输出链表反转后的元素,如没有元素则输出NULL. 样例输入: 5 1 2 3 4 5 0 样例输出: 5 4 3 2 1 NULL 解题思路:

剑指Offer:删除链表的节点【18】

剑指Offer:删除链表的节点[18] 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 题目分析 如上图所示,我们的定义了三个指针,其中第二.三个指针用于找到重复元素的第一个位置和最后一个位置的下一个位置,然后第一个指针的下一个指向三个指针,这样就跳过了重复元素. 但是编码发现后,还有两种情况欠考虑. 这种情况,刚开始,就是

剑指offer——两个链表的公共节点

题目链接:输入两个链表,找出它们的第一个公共结点. 解题思路: 找出2个链表的长度,然后让长的先走两个链表的长度差,然后再一起走(因为2个链表用公共的尾部) 1 /* 2 public class ListNode { 3 int val; 4 ListNode next = null; 5 6 ListNode(int val) { 7 this.val = val; 8 } 9 }*/ 10 public class Solution { 11 public ListNode FindFir