35_复杂链表的复制

复杂链表的复制

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

示例 1:
在这里插入图片描述


输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:
在这里插入图片描述


输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]

示例 3:
在这里插入图片描述

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

示例 4:

输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。

提示:

  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。
  • 节点数目不超过 1000 。

解法: 为了提高时间复杂度和空间复杂度的效率,采用复制结点到原链表上,然后再将原链表拆分成两条。
第一步:克隆结点
第二步:复制结点的random值到子结点上
第三步:将链表拆分成两条

遇到的问题: 此题涉及到的复制和断链过程比较复杂,中间多次出错。指针的指向问题的技巧也要多总结。
TODO: 指针的指向技巧总结

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
        if(head == nullptr)
            return nullptr;
        cloneNode(head);
        connectNode(head);
        return reConnectNode(head);
    }
    // 将所有结点克隆一份,跟在自己后面
    void cloneNode(Node*& head){
        Node* pNode = head;
        while(pNode != nullptr){
            Node* newNode = new Node(head->val);
            newNode->val = pNode->val;      // 注意这里的初始化
            newNode->next = pNode->next;
            newNode->random = nullptr;

            pNode->next = newNode;
            pNode = newNode->next;
        }
    }
    // 将原链表中的random信息赋值到复制的链表中
    void connectNode(Node*& head){
        Node* pNode = head;
        while(pNode != nullptr){
            Node* nextCloned = pNode->next;
            if(pNode->random != nullptr){
                nextCloned->random = pNode->random->next;
            }
            pNode = nextCloned->next;
        }
    }
    // 根据奇数和偶数将结点拆分为两条,一条为原始链,一条为复制链。
    Node* reConnectNode(Node*& head){
         Node* pNode = head;
         Node* clonedHead = pNode->next;
         Node* nextCloned = clonedHead;
         pNode->next = nextCloned->next;    // 注意
         pNode = pNode->next;
         while(pNode != nullptr){
             nextCloned->next = pNode->next;
             nextCloned = nextCloned->next;     // 注意
             pNode->next = nextCloned->next;
             pNode = pNode->next;
         }
         return clonedHead;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值